java中反射机制

什么是Java反射(Reflection)?

程序在运行时(不是编译时)能够自我检查,并且能够对内部成员进行操作。例如它允许一个java类获取他所有的变量和方法。利用java中反射机制可以通过Reflection API获取该类的内部信息,如superclass、interfaces、modifiers(修饰public、private等)、以及field和methods,并且运行中能够修改field和调用methods。java的这种反射机制使其被视为动态语言的关键因素。

反射可以做什么?

在运行中分析类的能力。

在运行中查看对象。

实现通用的数组操作代码。

利用Method对象。


Class类

java在运行是为每个对象维护一个类型标识,这个类型标识跟踪着这个对象所属的类。虚拟机通过这个类型标识获取类中相关信息,java将这些信息保存在Class类中。这个Class类不能够创建对象,不是因为其没有构造方法,而是因为他的构造方法是private类型,之所以用private类型,就是为了避免其他类构造该类的实例,这个类的实例是由虚拟机自己构造的。有了这个Class就可以通过反射获取类中的信息了。

  class Class<T> implements java.io.Serializable,
                              java.lang.reflect.GenericDeclaration,
                              java.lang.reflect.Type,
                              java.lang.reflect.AnnotatedElement {
    private static final int ANNOTATION= 0x00002000;
    private static final int ENUM      = 0x00004000;
    private static final int SYNTHETIC = 0x00001000;

    private static native void registerNatives();
    static {
        registerNatives();
    }

    /*
     * Constructor. Only the Java Virtual Machine creates Class
     * objects.
     */
    private Class() {}

获取Class类型

可以通过一下三种方式获取类的class类型。

1、通过Object的getClass()方法

比如,Employee e;

e.getClass();

2、通过Class类的静态方法forName()获取,注意这个需要添加异常处理器

Class.forName(className);

这个className包括包名的完整名称。

3、直接通过类名

Employee.class就是返回一个class类型


Class类提供的方法

通过class类提供的方法获取当前类的信息。


static Class<?>forName(String className)
Returns the Class object associated with the class or interface with the given string name.
static Class<?>forName(String name, boolean initialize, ClassLoader loader)
Returns the Class object associated with the class or interface with the given string name, using the given class loader.

通过forName获取class类型,第二种方式是指使了是否一定初始化以及指定类加载器


ClassLoadergetClassLoader()
Returns the class loader for the class.
Constructor<T>getConstructor(Class<?>... parameterTypes)
Returns a Constructor object that reflects the specified public constructor of the class represented by this Class object.
Constructor<?>[]getConstructors()
Returns an array containing Constructor objects reflecting all the public constructors of the class represented by this Class object.


通过getClassLoader()获取当前类的类加载器。

getConstructor()返回当前类的构造方法,第一个paramterTyper是指示特定获取构造方法的指定参数类型的构造器

Constructor类型稍后说


FieldgetField(String name)
Returns a Field object that reflects the specified public member field of the class or interface represented by this Class object.
Field[]getFields()
Returns an array containing Field objects reflecting all the accessible public fields of the class or interface represented by this Class object.


返回公共变量,指定参数的话获取特定参数的变量Field,getFields()获取所有公共域变量。


MethodgetMethod(String name,Class<?>... parameterTypes)
Returns a Method object that reflects the specified public member method of the class or interface represented by this Class object.
Method[]getMethods()
Returns an array containing Method objects reflecting all the public member methods of the class or interface represented by this Class object, including those declared by the class or interface and those inherited from superclasses and superinterfaces.


返回该类的公共方法,包括由父类或着接口继承过来的


Constructor<T>getDeclaredConstructor(Class<?>... parameterTypes)
Returns a Constructor object that reflects the specified constructor of the class or interface represented by this Class object.
Constructor<?>[]getDeclaredConstructors()
Returns an array of Constructor objects reflecting all the constructors declared by the class represented by this Class object.
FieldgetDeclaredField(String name)
Returns a Field object that reflects the specified declared field of the class or interface represented by this Class object.
Field[]getDeclaredFields()
Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object.
MethodgetDeclaredMethod(String name,Class<?>... parameterTypes)
Returns a Method object that reflects the specified declared method of the class or interface represented by this Class object.
Method[]getDeclaredMethods()
Returns an array of Method objects reflecting all the methods declared by the class or interface represented by this Class object.

这些方法与上面的方法类似,但是他们是类中声明的全部域,全部方法,全部构造器,包括私有和受保护的,但是不包括超类的。而之前的不带Declared是返回当前类共有的变量、方法、构造方法,包括父类和接口的


intgetModifiers()
Returns the Java language modifiers for this class or interface, encoded in an integer.
StringgetName()
Returns the name of the entity (class, interface, array class, primitive type, or void) represented by this Class object, as a String.


返回该类的修饰类型,这个返回的是一个整形的编码,对应着其类型public, protected, private, final, static, abstract and interface,这些需要使用Modifier类进行解析。

getName()获取当前了类的完整类名


booleanisInterface()
Determines if the specified Class object represents an interface type.
booleanisLocalClass()
Returns true if and only if the underlying class is a local class.
booleanisPrimitive()
Determines if the specified Class object represents a primitive type.
booleanisSynthetic()
Returns true if this class is a synthetic class; returns false otherwise.
TnewInstance()
Creates a new instance of the class represented by this Class object.
StringtoString()
Converts the object to a string.


Class还提供了许多isXxx用来类型判断

newInstance()快速获取该类的实例,但是只能使用该类的无参构造方法,因为没有提供有参的构造方法,所以必须保证该类有无参构造方法。之后可以通过Constructor类的newInstance()提供含参的构造方法。


java.lang.reflect反射api接口


这里面有Field、Method、Constructor、Modifier类,都是之前提到类

AccessiableObject类:是Field、Method、Constructor的超类,其中方法setAccessible设置为true可以设置允许访问私有域

Array类:提供了动态生成和访问数组的类

Field类:提供类的域的信息,以及访问域的接口

Constructor类:提供了类的构造方法的信息,以及访问构造方法的接口

Modifier类:提供了类的方法信息,以及访问该类方法的接口

通过代码来看获取这些信息:

class ReflectionTest{
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String name = scanner.next();
		
		try{
			Class c1 = Class.forName(name);
			Class superCl = c1.getSuperclass();
			System.out.println("superClass"+superCl.getName());
			String modifilter = Modifier.toString(c1.getModifiers());
			System.out.println("modifiers:" + modifilter );
			
			printContruct(c1);
		}catch(ClassNotFoundException e){
			e.printStackTrace();
		}
		System.exit(0);
	}
	
	public static void printContruct(Class c1){
		System.out.println("*********打印Constructor*********");
		Constructor[] construct = c1.getConstructors();
		for (Constructor c : construct) {
			System.out.println("该构造方法所属类:" + c.getName());
			System.out.println("使用Modifier类:" +Modifier.toString(c.getModifiers())  );
			Class[] paramTypes = c.getParameterTypes();

			for (Class class1 : paramTypes) {
				System.out.println("参数类型:"+class1.getName());
			}
			System.out.println("toString方法:" + c.toString());
		}
		
	}
	
	public static void printField(Class c1) throws IllegalArgumentException, IllegalAccessException{
		
		System.out.println("*********打印Field*********");
		Field[] fields = c1.getFields();
		for (Field field : fields) {
			System.out.println("获取所属类:" +field.getName());
			System.out.println(Modifier.toString(field.getModifiers()));
			System.out.println("获取type" + field.getType());
			Object b = new ReflectionTest();
			System.out.println("get()方法做什么用的:"+field.get(b));//对应还有getDouble(),getInt()....
		}
	}
	
	public static void printMethod(Class c1){

		System.out.println("*********打印Method*********");
		Method[] method = c1.getDeclaredMethods();
		for (Method m : method) {
			System.out.println(m.getName());
			System.out.println(m.getReturnType());//获取返回类型
			m.invoke(obj, args)//允许调用包装在Method对象中的方法。
		}
	}
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值