Class类:
所有类的对象实际上都是class类的一个实例。Java.lang.Class
当一个类被加载以后,JVM会生成可执行的代码和数据
还会在堆内存中创建一个对应的该类的class对象
这个class类对象中包含该类的整个结构信息
同一个类只能被java虚拟机加载一次,在堆内存中是唯一存在的
类的使用
1.Class.forName()最常用
反射的基本原理:
Class类实际上是java反射的源头
反射机制,java动态获取指定的类以及动态调用类中的内容
在程序运行过程中,通过已知的对象信息来找到所属类,并将该类加载到内存中,通过反射
来新建对象
反射应用场景:
如果编码时,不知道类的具体信息,就可以通过已知对象来获取对象所在的类的信息
保留无参的构造方法
类。Class
对象。Getclass
取得类的全名称
取得类属性的信息field类
取得public类型的全部信息,返回一个对象数组
可以获得私有属性:
获得指定属性:
获取类的方法信息:Method类
取得类的构造器信息Constructor类
取得public类型
取得所有类型的构造器信息
获得某一个构造器:
获取继承的父类信息:
取得所实现的全部接口信息:
利用无参构造器创建对象
Newinstance方法:
利用有参的构造器创建一个对象:
利用反射API,调用普通方法
利用反射API,操作属性:
实操:
本示例使用Java反射机制分别设置当前类的private、public属性以及其父类的private属性来说明如何通过Java反射机制设置属性值。(注:设置继承的父类属性时,无法通过当前类的Class对象直接获取其属性字段,须通过其父类Class对象得到Field对象操作)
首先,建立父类User
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
建立子类Student继承User
public class Student extends User {
//学号
private String stuNo;
//专业
public String major;
public String getStuNo() {
return stuNo;
}
public void setStuNo(String stuNo) {
this.stuNo = stuNo;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
}
新建测试类
public class Test {
public static void main(String[] args) throws Exception {
Object stu = new Student();
Class clazz = stu.getClass();
System.out.println("-------设置当前类stuNo(private)属性---------------");
System.out.println("Before stuNo:"+((Student)stu).getStuNo());
Field stuNo = clazz.getDeclaredField("stuNo");//通过反射获取stuNo字段
stuNo.setAccessible(true);//private属性必须设置
stuNo.set(stu,"13201233");
System.out.println("After stuNo:"+((Student)stu).getStuNo());
System.out.println("-------设置当前类major(public)属性---------------");
System.out.println("Before major:"+((Student)stu).getMajor());
Field major = clazz.getDeclaredField("major");//通过反射获取stuNo字段
major.set(stu,"软件工程");
System.out.println("After major:"+((Student)stu).getMajor());
System.out.println("-------设置继承的父类name属性------------");
System.out.println("Before name:"+((Student)stu).getName());
Field name = clazz.getSuperclass().getDeclaredField("name");//通过反射获取父类name字段
name.setAccessible(true);//private属性必须设置
name.set(stu,"Edward");
System.out.println("After name:"+((Student)stu).getName());
}
}
运行结果:
-------设置当前类stuNo(private)属性---------------
Before stuNo:null
After stuNo:13201233
-------设置当前类major(public)属性---------------
Before major:null
After major:软件工程
-------设置继承的父类name属性------------
Before name:null
After name:Edward
注意:设置private属性值时,必须设置setAccessible(true),否则会抛出如下异常:
Exception in thread "main" java.lang.IllegalAccessException: Class cn.ll.test.Test can not access a member of class cn.ll.test.Student with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Field.set(Field.java:761)
at cn.ll.test.Test.main(Test.java:17)