class类
什么是反射?
反射就是Reflection,Java的反射是指程序在运行期可以拿到一个对象的所有信息。
方法一:直接通过一个class
的静态变量class
获取:
Class cls = String.class;
方法二:如果我们有一个实例变量,可以通过该实例变量提供的getClass()
方法获取:
String s = "Hello";
Class cls = s.getClass();
方法三:如果知道一个class
的完整类名,可以通过静态方法Class.forName()
获取:
Class cls = Class.forName("java.lang.String");
访问字段
Class
类提供了以下几个方法来获取字段:
- Field getField(name):根据字段名获取某个public的field(包括父类)
- Field getDeclaredField(name):根据字段名获取当前类的某个field(不包括父类)
- Field[] getFields():获取所有public的field(包括父类)
- Field[] getDeclaredFields():获取当前类的所有field(不包括父类)
import java.lang.reflect.Field;
public class ErrorDemo{
public static void main(String[] args) throws Exception{
// 获取字段值
//Object p = new Person("xiaoshuai");
//Class c = p.getClass();
//Field f = c.getDeclaredField("name");
//
//f.setAccessible(true); // 允许访问隐藏字段
//Object value = f.get(p);
//System.out.println(value);
// 设置字段值
Person p = new Person("xiaoshuai");
System.out.println(p.getName());
Class c = p.getClass();
Field f = c.getDeclaredField("name");
f.setAccessible(true);
f.set(p,"shao shuai");
System.out.println(p.getName());
}
}
class Person{
//public String name;
private String name;
public Person(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
// 通过反射读写字段是一种非常规方法,它会破坏对象的封装。
调用方法
public class ErrorDemo{
public static void main(String[] args) throws Exception{
Class stdClass = Student.class;
// 获取public方法getScore,参数为String:
System.out.println(stdClass.getMethod("getScore", String.class));
// 获取继承的public方法getName,无参数:
System.out.println(stdClass.getMethod("getName"));
// 获取private方法getGrade,参数为int:
System.out.println(stdClass.getDeclaredMethod("getGrade", int.class));
}
}
class Person{
public String getName(){
return "Person";
}
}
class Student extends Person{
public int getScore(String type){
return 99;
}
private int getGrade(int year){
return 1;
}
}
调用方法
/*
Constructor对象封装了构造方法的所有信息;
通过Class实例的方法可以获取Constructor实例:getConstructor(),getConstructors(),getDeclaredConstructor(),getDeclaredConstructors();
通过Constructor实例可以创建一个实例对象:newInstance(Object... parameters); 通过设置setAccessible(true)来访问非public构造方法。
*/
获取继承关系
Class i = String.class; // 获取到String的Class
Class s = i.getSuperclass(); // 获取到i对象的父类
// 通过Class对象可以获取继承关系:
// Class getSuperclass():获取父类类型;
// Class[] getInterfaces():获取当前类实现的所有接口。
// 通过Class对象的isAssignableFrom()方法可以判断一个向上转型是否可以实现。
动态代理
Java标准库提供了动态代理功能,允许在运行期动态创建一个接口的实例;
动态代理是通过Proxy创建代理对象,然后将接口方法“代理”给InvocationHandler完成的。