文章目录
Java 反射总结
概述
Java的反射是指程序在运行期可以拿到一个对象的所有信息。
Java可以通过反射实现一下功能:
- 创建一个类的对象。
- 访问对象的成员变量和方法。
在Android中,出于安全考虑,google对系统的某些方法使用@hide
或private
修饰,导致不能正常调用该方法,这时可以借助反射进行操作。
Class实例
Class是一个类,里面包含类的所有信息,如:属性、方法、构造函数等。
定义实体类:
public class Person extends People implements Serializable {
private String name;
private int age;
public String address;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
private Person(int age, String address) {
this.age = age;
this.address = address;
}
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public String setName(String name) {
this.name = name;
return "666";
}
private String setRealName(String name) {
this.name = name;
return name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
private void setAddress(String address) {
this.address = address;
}
public static String getCountry() {
return "中国";
}
public String showDetail() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
获取Class对象
//方式一:通过类名获取
Class<Person> clazz = Person.class;
//方式二:通过对象获取
Person person = new Person();
Class<? extends Person> clazz = person.getClass();
//方式三:通过Class.forName()获取
Class<?> clazz = Class.forName("com.example.myapplication.Person");
instanceof & isInstance() & isAssignableFrom()区别
- instanceof:是一个关键字,用于判断对象是否为类的实例。
- isInstance():是Class类中的方法,判断是否为类的实例。
- isAssignableFrom():是Clas类s中的方法,判断继承关系。
//instanceof
System.out.println(fruit instanceof Fruit);//true
System.out.println(apple instanceof Apple);//true
System.out.println(apple instanceof Fruit);//true
// System.out.println("hello" instanceof Fruit);//报错
//isInstance
System.out.println(Fruit.class.isInstance(fruit));//true
System.out.println(Apple.class.isInstance(apple));//true
System.out.println(Fruit.class.isInstance(apple));//true
System.out.println(Fruit.class.isInstance("hello"));//false
//isAssignableFrom
System.out.println(Fruit.class.isAssignableFrom(Fruit.class));//true
System.out.println(Apple.class.isAssignableFrom(Apple.class));//true
System.out.println(Fruit.class.isAssignableFrom(Apple.class));//true
System.out.println(Fruit.class.isAssignableFrom(String.class));//false
获取Class信息
Class<String> clazz = String.class;
//获取全类名
String name = clazz.getName();
System.out.println(name); //java.lang.String
//获取全类名
String canonicalName = clazz.getCanonicalName();
System.out.println(canonicalName); //java.lang.String
//获取类名
String simpleName = clazz.getSimpleName();
System.out.println(simpleName); //String
//获取报名
Package pkg = clazz.getPackage();
System.out.println(pkg.getName()); //java.lang
//获取父类
Class<? super String> superclass = clazz.getSuperclass();
System.out.println(superclass.getName()); //java.lang.Object
//获取当前实现的接口
Class<?>[] interfaces = clazz.getInterfaces();
for (Class i : interfaces) {
System.out.println(i.getName());
}
/*
java.io.Serializable
java.lang.Comparable
java.lang.CharSequence
*/
通过Class创建对象
//通过Class实例创建实例对象
Person person = clazz.newInstance();
访问构造函数
获取Constructor对象
//获取public构造方法
Constructor[] constructors = clazz.getConstructors();
//获取所有构造方法
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
//获取指定参数的public构造方法
Constructor constructor = clazz.getConstructor(String.class, int.class);
//获取指定参数的非public构造方法
Constructor constructor = clazz.getDeclaredConstructor(int.class, String.class);
通过构造函数创建对象
Constructor<Person> constructor = Person.class.getConstructor(String.class, int.class, String.class);
Person p = constructor.newInstance("小白", 18, "北京市");
调用方法
获取Method对象
//获取当前类和父类的public方法
Method[] methods = clazz.getMethods();
//获取当前类的所有方法
Method[] methods = clazz.getDeclaredMethods();
//根据方法名和参数Class对象,获取当前类和父类的public方法
Method method = clazz.getMethod("setName", String.class);
//根据方法名和参数Class对象,获取当前类的方法,无限制
Method method = clazz.getDeclaredMethod("setAddress", String.class);
获取Method信息
//获取方法名
String methodName = method.getName();
//获取返回值类型
Class<?> returnType = method.getReturnType();
//获取参数类型
Class<?>[] parameterTypes = method.getParameterTypes();
//获取修饰符
int modifiers = method.getModifiers();
调用普通方法
//获取指定方法
Method method = clazz.getMethod("setName", String.class);
//调用方法并获取返回值
String ret = (String) method.invoke(p, "小红");
调用非public方法
Method method = clazz.getDeclaredMethod("setRealName", String.class);
method.setAccessible(true);
String ret = (String) method.invoke(p, "小花");
调用静态方法
静态方法无需指定实例对象,所以invoke()的第一个参数永远为null。
Method method = clazz.getMethod("getCountry");
String ret = (String) method.invoke(null);
访问字段
获取Field对象
//获取当前类和父类的public属性
Field[] fields = clazz.getFields();
//获取当前类的所有属性
Field[] fields = clazz.getDeclaredFields();
//获取当前类和父类的public属性
Field field = clazz.getField("address");
//获取当前类的属性,无限制
Field field = clazz.getDeclaredField("name");
获取Field信息
//获取字段名
String fieldName = field.getName();
//获取字段类型
Class<?> fieldType = field.getType();
//获取字段修饰符
int fieldModifiers = field.getModifiers();
//是否为private修饰
boolean isPrivate = Modifier.isPrivate(fieldModifiers);
获取字段值
Person p = new Person("小明", 18, "北京市");
Class<? extends Person> clazz = p.getClass();
Field f = clazz.getDeclaredField("name");
f.setAccessible(true);//非public设为true
Object value = f.get(p);
System.out.println(value);//小明
设置字段值
Person person = clazz.newInstance();
Field name = clazz.getDeclaredField("name");
name.setAccessible(true);//非public设置true
name.set(person, "小白");