反射技术:
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
简单一句话:反射技术可以对类进行解剖。所有的类文件都有共同属性,所以可以向上抽取,把这些共性内容封装成一个类,这个类就叫Class(描述字节码文件的对象)。
Class类中就包含属性有field(字段)、method(方法)、construction(构造函数)。
而field中有修饰符、类型、变量名等复杂的描述内容,因此也可以将字段封装称为一个对象。用来获取类中field的内容,这个对象的描述叫Field。同理方法和构造函数也被封装成对象Method、Constructor。要想对一个类进行内容的获取,必须要先获取该字节码文件的对象。该对象是Class类型。
Class类描述的信息:类的名字,类的访问属性,类所属于的包名,字段名称的列表,方法名称的列表等。每一个字节码就是class的实例对象
//该类用于反射基类
public class RelfletDemo {
//私有变量str
private String str = "privatestr";
static int num = 8;
//私有的方法
private void reflectMethod() {
System.out.println("private feflectMethod()...........");
}
//静态方法
public static void publicMethod(String str, int num) {
System.out.println("public publicMethod()..........." + str + num);
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
该类用于获取字节码文件,私有字段,静态方法,私有方法等演示:
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Bolg8 {
/**
* @param args
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws NoSuchFieldException
* @throws SecurityException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalArgumentException
*/
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchFieldException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
// TODO Auto-generated method stub
//获取字节码文件
Class clazz = Class.forName("com.itheima.blog.RelfletDemo");
//创建此 Class 对象所表示的类的一个新实例。
Object obj = clazz.newInstance();
//返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。获取"str"字段
Field field1 = clazz.getDeclaredField("str");
//暴力反问私有的变量
field1.setAccessible(true);
System.out.println(field1.get(obj));
//返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。获取"num"字段的Field对象
Field field2 = clazz.getDeclaredField("num");
System.out.println(field2.get(obj));
// 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 该方法名是"reflectMethod",没有参数
Method method = clazz.getDeclaredMethod("reflectMethod", null);
//暴力访问
method.setAccessible(true);
//对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。 实例对象是 obj
method.invoke(obj, null);
// 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 该方法名是"publicMethod",参数是parameterTypes - 参数列表 String.class int.class
Method method1 = clazz.getMethod("publicMethod", String.class,int.class);
//对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。 实例对象是 obj 参数是String "黑马num" 和int 1
method1.invoke(null, "黑马num",1);
}
}