//反射,为了获取类的相关信息
// Class 为类名的类,如下
/*
public final class Class
{
private Class(){}
}
*/
// 以String为例,当JVM读取到一种class类型时,将其加载进内存,
// 每加载一种class,JVM就为其创建一个Class类型的实例,并关联起来
// Class cls = new Class(String);
// JVM 在该实例中保存了该class的所有信息,先获取该Class实例,在获取对应的class的所有信息
// 通过Class获取class信息的方法————反射
// 方法1,通过静态变量class获取
Class cls = String.class;
// 方法2,通过实例变量的getClass()获取
String s = "";
Class cls1 = s.getClass();
// 方法3,知道class的完整类名,通过静态方法Class.forName()获取
Class cls2 = Class.forName("java.lang.String");
// 由于Class实例在JVM中式唯一的,所以上述方法获得的实例是同一个实例
printClassInfo(String[].class);
}
//String && String[] 不是一种Class实例
//Jvm 动态加载class,只有程序用到的类才会加载出Class的实例
static void printClassInfo(Class cls)
{
System.out.println("Class name:"+cls.getName());
System.out.println("Simple name:" + cls.getSimpleName());
System.out.println(cls.isInterface());
System.out.println(cls.isArray());
System.out.println(cls.isPrimitive());
//访问字段
Class stuCls = Student.class;
System.out.println(stuCls.getField("score"));
// Field stuCls.getField("string"));//包含父类,arg string
// Field[] stuCls.getFields();//包含父类
// Field stuCls.getDeclaredField("string"); //不包含父类,arg string
// Field[] stuCls.getDeclaredFields(); //不包含父类
//获取字段值, 先拿到这个字段的Field,在获取这个实例的字段的值
// Object o = new Person("xiaoming");
// Class cls = o.getClass();
// Field f = cls.getDeclaredField("name");
// f.setAccessible(true);// 不管字段值是public 还是 private 都可以获取
// Object value = f.get(o);// 获取字段值
// System.out.println(value);
// 设置字段值
Person p = new Person("xiaoming");
Class cls = p.getClass();
Field f = cls.getDeclaredField("name");
f.set(p, "xiaowang");
System.out.println(p.name);
// 通过反射会破坏数据的封装
class Student extends Person
{
public int score;
public Student(String name)
{
super(name);
}
}
class Person
{
public String name;
public Person(String name)
{
this.name = name;
}
}
练习:
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
String name = "Xiao Ming";
int age = 20;
Person p = new Person();
// TODO: 利用反射给name和age字段赋值:
Class cls = p.getClass();
Field fn = cls.getDeclaredField("name");
Field fa = cls.getDeclaredField("age");
fn.setAccessible(true);
fa.setAccessible(true);
fn.set(p, "Xiao Ming");
fa.set(p, 20);
System.out.println(p.getName()); // "Xiao Ming"
System.out.println(p.getAge()); // 20
}
}
class Person {
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;
}
}