java反射
java反射机制: 在运行中对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java的反射机制是在编译并不确定是哪个类被加载了,而是在程序运行的时候才加载、探知、自审。使用在编译期并不知道的类,这种特点就是反射。
三种反射方式:(拿到字节码文件Class,就可以创建对象)
`
// 测试的学生类
public class Student {
private int age ; //私有属性
private String family; //私有属性
public String name;
public Student(){
}
private Student(String name){ //私有构造函数
this.name = name;
System.out.println("你调用了构造函数");
}
public Student(int age, String name) {
super();
this.setAge(age);
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getFamily() {
return family;
}
public void setFamily(String family) {
this.family = family;
}
@Override
public String toString() { //重写
return "Student [age=" + age + ", family=" + family + ", name=" + name
+ "]";
}
} private String secret(String s){
String result=null;
return result="这位同学有个秘密"+s;
}
}
`
`
public class Test {
/**
* @param args
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//第一种:继承Object类的getclass()方法
Student s = new Student();
Class clazz1 = s.getClass();
//第二种:静态属性class属性,锁对象。
Class clazz2 =Student.class;
//第三种:Class类中的静态方法forname(),读取配置文件
//实现了通过字节码文件创建对象。
Class clazz3 = Class.forName("com.hawdee.Student");
Student instance = (Student) clazz3.newInstance();
}
}
`
`
public class Test2 {
//此处抛出异常太多,为了简洁抛出Exception
public static void main(String[] args) throws Exception{
test1();
}
public static void test1() throws Exception{
Class<?> clazz = Class.forName("com.hawdee.Student");//取得字节码文件clazz
Constructor<?> constructor = clazz.getDeclaredConstructor(String.class);
constructor.setAccessible(true);
Object object = constructor.newInstance("女同学");//通过构造器创建对象
Student s = (Student)object;
Field field1 = clazz.getDeclaredField("age");
field1.setAccessible(true);
Object object1 = field1.get(s);
Integer age = (Integer) object1;
System.out.println(age);
field1.set(s, 18);
System.out.println(s);
Field field2 = clazz.getDeclaredField("family");//得到字段对象
field2.setAccessible(true); //对私有字段中的私有成员变量授权为public
Object object2 = field2.get(s); //通过字段获取Student对象
String family = (String)object2; //把object类的对象转为String类
System.out.println(family);
field2.set(s, "一家四口人");//通过字段设定对象的属性
System.out.println(s);
}
// 类似我们通过反射获取类的成员方法
public static void testMethod() throws Exception{
Class<?> clazz = Class.forName("com.hawdee.Student");
Object object = clazz.newInstance();
Student s = (Student)object;
Method method2 = clazz.getDeclaredMethod("secret", String.class); //得到方法类的对象
method2.setAccessible(true); //设置权限
Object result = method2.invoke(s,"这个秘密不能说"); //调用这个私有方法
System.out.println(result);
}
}
`
测试代码输出如下