Java之------类反射系列(一)

本博客同系列有:

Java之------类反射系列(二)

Java之------类反射系列(三)

什么是类反射

☆什么是反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。

反射(Reflection)是Java程序开发语言的特征之一,它允许运行中的Java程序对自身进行检查, 也称自审,并能直接操作程序的内部属性。例如,使用它能获得Java类中各成员的名称并显示出来。

Java的这一能力在实际应用中应用得很多,在其它的程序语言中根本就不存在这一特性。例如,Pascal、C或者C++中就没有办法在程序中获得函数定义相关的信息。

JavaBean是类反射的实际应用之一,它能让一些工具可视化的操作软件组件。这些工具通过类反射动态的载入并取得Java组件(类)的属性。后面学习的各种框架,基本上都会有反射的使用。

反射引例:

HelloWorld引例:

package cn.hncu.hello;

import java.lang.reflect.Method;

public class ReflectionHelloWorld {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			Class c=Class.forName("cn.hncu.introduce.Person");//必须写完整类名
//			System.out.println(c);
			Method ms[] = c.getDeclaredMethods();
			for (Method m:ms){
				System.out.println(m);
			}
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
	}
}
USB引例:

此例在导入类名的时候采用的是:新建一个.config文件,在该文件中写上需要导的类的全名,然后在要使用的时候采用IO读取里面的内容,里面一次只存放一个类名,其他需要用的可在前面加上“#”号做注释,如下为usb.config文件:

#name=cn.hncu.usb.impl.UsbOne
#name=cn.hncu.usb.impl.UsbTwo
name=cn.hncu.usb.impl.UsbMouse
USB接口:

package cn.hncu.usb.api;

public interface USB {
    public void work();
}
实现类(本来写了多个,但只是类名不同,其他都是类似的,于是只写一个示范了):

package cn.hncu.usb.impl;

import cn.hncu.usb.api.USB;

public class UsbOne implements USB {

	@Override
	public void work() {
		System.out.println("UsbOne.............");
		
	}
}
工厂类:

package cn.hncu.usb.factory;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

import cn.hncu.usb.api.USB;

public class UsbFactory {
	public static USB getUsb(){
		USB usb=null;
		try {
			Properties p=new Properties();
			FileInputStream fis=new FileInputStream(new File("usb.config"));<span style="font-family: Arial, Helvetica, sans-serif;">//这就是前面提到的导入usb.config里的类名</span>
			p.load(fis);
			String fileName=p.getProperty("name");//此"name"为usb.config中的key值,可得到相应的value
			Class c=Class.forName(fileName);
			usb=(USB) c.newInstance();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return usb;
	}
}
模拟客户端:

package cn.hncu.usb;

import cn.hncu.usb.api.USB;
import cn.hncu.usb.factory.UsbFactory;

public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		USB usb=UsbFactory.getUsb();
		usb.work();
	}
}

运行结果:

Java之------类反射系列(一)_第1张图片

获取Class对象的三种方式
★ 方式一

通过对象的getClass方法进行获取。这种方式需要具体的类和该类的对象,以及调用getClass方法。

★ 方式二

任何数据类型(包括基本数据类型)都具备着一个静态的属性class,通过它可直接获取到该类型对应的Class对象。这种方式要使用具体的类,然后调用类中的静态属性class完成,无需调用方法,性能更好。

★ 方式三

通过Class.forName()方法获取。这种方式仅需使用类名,就可以获取该类的Class对象,更有利于扩展。

举例:

package cn.hncu.reflect;

public class ReflectGetClass {

	/**
	 * @param args
	 * Three manners to get the object of Class
	 */
	public static void main(String[] args) {
		getClassObj1();
		getClassObj2();
		getClassObj3();
		
		test();
	}

	private static void test() {
		Person p=new Person();
		Object obj=(Object)p;
		Class c=obj.getClass();//运行时多态,new谁调谁
		System.out.println(c);//class cn.hncu.reflect.Person
		
		System.out.println(int.class);//int
		System.out.println(Integer.class);//class java.lang.Integer
		System.out.println(Integer.TYPE);//int
	}

	private static void getClassObj3() {
		//3用字符串(类名)---依赖于String类
		try {
			Class c=Class.forName("cn.hncu.reflect.Person");
			System.out.println(c);
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	private static void getClassObj2() {
		//2通过类名----依赖于Person类
		Class c=Person.class;
		System.out.println(c);
	}

	private static void getClassObj1() {
		//1通过对象
		Person p1=new Person();
		Class c1=p1.getClass();
		
		Person p2=new Person();
		Class c2=p2.getClass();
		
		System.out.println(p1==p2);//不同的对象
		System.out.println(c1==c2);//同一个类模板,所有对象是共享同一个类模板的
	}
}


你可能感兴趣的:(java,类反射)