Java中的反射

一:反射的基础概念

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

 

    Class 类十分特殊。它和一般类一样继承自Object,其实体用以表达Java程序运行时的classes和interfaces,也用来表达enum、array、primitive Java types(boolean, byte, char, short, int, long, float, double)以及关键词void。当一个class被加载,或当加载器(class loader)的defineClass()被JVM调用,JVM 便自动产生一个Class 对象。

 

    区分两个概念:类的对象与类对象。

    类的对象:基于某个类的模版  new  出来的对象,也称为实例对象 。

    类对象:类加载的产物,封装了一个类的所有信息(类名、父类、接口、

    属性、方法、构造方法)

 

 

 

二:获取类对象的三种方式

 

        ①  通过类的对象,获取类对象

            •  Student s = new Student();

            •  Class c = s.getClass();  //Object的getClass()方法

        ② 通过类名获取类对象

            •  Class c =  类名 .class;

        ③  通过静态方法获取类对象

            •  Class c=Class.forName(包名. . 类名

 

三:Class类的API

Class类位于java.lang包下。 

根据类对象我们可以获取到包名、类名、类的构造方法、方法、属性等基本信息。

Array Constructor Field Method 这些类信息,被封装成不同的类,位于java.lang.reflect包下。

 

 Constructor<T>

getConstructor(Class<?>... parameterTypes) 
  返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。

 Constructor<?>[]

getConstructors() 
  返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。

 Constructor<T>

getDeclaredConstructor(Class<?>... parameterTypes) 
  返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。

 Constructor<?>[]

getDeclaredConstructors() 
  返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。

 Field

getDeclaredField(String name) 
  返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。

 Field[]

getDeclaredFields() 
  返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。

 Method

getDeclaredMethod(String name, Class<?>... parameterTypes) 
  返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。

 Method[]

getDeclaredMethods() 
  返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

 Method

getMethod(String name, Class<?>... parameterTypes) 
  返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。

 Method[]

getMethods() 
  返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。

 String

getName() 
  以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。

 Package

getPackage() 
  获取此类的包。

 

四:基于反射完成对私有方法(属性)的访问与万能方法

    Method类重要的方法。

 Object

invoke(Object obj, Object... args) 
  对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。

①:私有方法的访问

①:私有方法的访问
	public static void main(String[] args) throws Exception {
		//1:获取类对象
		Class c=Student.class;
		//2:通过Class对象,构建该Class所代表的类的一个实例
		Student s=(Student)c.newInstance();
		//3:获取类中的私有方法 showInfo()无参传Null
		 Method m= c.getDeclaredMethod("showInfo", null);
		 //4:将该方法设置为可访问
		 m.setAccessible(true);
		 //5:①实参②根据方法形参传递实参
		 m.invoke(s,null);
	}

class Student{
	public String name;
	private Integer age;
	
	public Student(){
		
	}
	public Student(String name,Integer age){
		this.name=name;
		this.age=age;
	}
	private void showInfo(){
		System.out.println("name:"+this.name+" age:"+this.age);
	}
}

 

 

②:万能方法的构建(一个方法只能有一个可变长参数,所以将参数类型封装  Class数组

 

public static void main(String[] args) throws Exception {
		//		对象实例			方法名			参数类型			实参
		method(new Worker() , "sayHi" , new Class[]{int.class} , 20);	
	}

	// 万能方法(可调用任何一个对象的实例方法)  
	public static void method(Object obj, String methodName, Class[] params, Object... values) throws Exception {
		// 获取类对象
		Class c = obj.getClass();

		// 获取Method对象
		Method m = c.getMethod(methodName, params);

		// 调用invoke()
		m.invoke(obj, values);
	}


class Worker {
	public void sayHi() {

	}

	public void sayHi(int n) {
		System.out.println("Hello");
	}

	public void sayHi(int n, int x)  {

	}
}

 

猜你喜欢

转载自blog.csdn.net/Sugar_map/article/details/79734578