反射机制
User类
package com.lzy.test.bean;
public class User {
private int id;
private int age;
private String uname;
public User(int id, int age, String uname) {
super();
this.id = id;
this.age = age;
this.uname = uname;
}
public User() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
}
Demo01
package com.lzy.test.bean;
public class Demo01 {
public static void main(String[] args) {
String path="com.lzy.test.bean.User";
try {
Class clazz=Class.forName(path);
//对象是表示或封装一些数据。 一个类被加载后,JVM会创建一个对应该类的Class对象,类的整个结构信息会放到对应的Class对象中。
//这个Class对象就像一面镜子一样,通过这面镜子我可以看到对应类的全部信息。
System.out.println(clazz.hashCode());
Class clazz2=Class.forName(path);
System.out.println(clazz2.hashCode());
Class strClazz=String.class;
Class strClazz2=path.getClass();
System.out.println(strClazz.hashCode());
System.out.println(strClazz2.hashCode());
System.out.println(strClazz==strClazz2);
Class intClazz=int.class;
int[] arr01 = new int[10];
int[][] arr02 = new int[30][3];
int[] arr03 = new int[30];
double[] arr04 = new double[10];
System.out.println(arr01.getClass().hashCode());
System.out.println(arr02.getClass().hashCode());
System.out.println(arr03.getClass().hashCode());
System.out.println(arr04.getClass().hashCode());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果:
798154996
798154996
681842940
681842940
true
1392838282
523429237
1392838282
664740647
10行和13行的hashCode一样,说明同样的类只会被加载一次,加载一次后会形成一个Class对象
15 16行都是String类,所以hashCode也同样一样
arr01和arr03虽然数组长度不一样,但都是一维数组,同样hashCode一样
通过反射API动态的操作:构造器、方法、属性
package com.lzy.test.bean;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Demo03 {
public static void main(String[] args) {
String path="com.lzy.test.bean.User";
try {
Class<User> clazz=(Class<User>)Class.forName(path);
//通过反射API调用构造方法,构造对象
User u=clazz.getDeclaredConstructor().newInstance();//其实调用了User的无参构造方法
System.out.println(u);
Constructor <User> c=clazz.getDeclaredConstructor(int.class,int.class,String.class);
User u2=c.newInstance(1001,18,"lzy");
System.out.println(u2.getUname());
//通过反射API调用普通方法
User u3=clazz.getDeclaredConstructor().newInstance();
Method method=clazz.getDeclaredMethod("setUname", String.class);
method.invoke(u3, "lzy2");//u3.setUname("lzy2");
System.out.println(u3.getUname());
//通过反射API操作属性
User u4=clazz.getDeclaredConstructor().newInstance();
Field f=clazz.getDeclaredField("uname");
f.setAccessible(true); //这个属性不需要做安全检查了,可以直接访问
f.set(u4, "lzy4");//通过反射直接写属性
System.out.println(u4.getUname());//通过反射直接读属性的值
System.out.println(f.get(u4));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
15 18 23 29行即:
User u=clazz.getDeclaredConstructor().newInstance();//其实调用了User的无参构造方法
Constructor <User> c=clazz.getDeclaredConstructor(int.class,int.class,String.class);
User u3=clazz.getDeclaredConstructor().newInstance();
User u4=clazz.getDeclaredConstructor().newInstance();
曾经写法为:User u=clazz.newInstance();,但已被取代,上面为正确方法。
User u=clazz.newInstance();