常用类
可以查看api文档,都是在java.lang.reflect包下面
四大常用类
- Class类 获取需要加载的类
- Field类 获取该类的属性字段
- Method类 获取该类的方法
- Constructor类 获取该类的构造器
实例
public static void main(String[] args) throws Exception {
//反射入门
Properties properties = new Properties();
properties.load(new FileInputStream("src\\re.properties"));
//获取类名和需要使用的方法
String classfull = properties.getProperty("classfull");
String methodName = properties.getProperty("method");
//加载对应的类对象 Class类对象 classfull
Class<?> aClass = Class.forName(classfull);
// 通过Class类对象获取相应类的对象,运行类型为com.hly.reflection.Cat
Object o = aClass.newInstance();
// 获取类相关信息,直接获取的只有公有成员
// 通过类加载对象获取相应的方法
Method method = aClass.getMethod(methodName);
//调用方法,方法.invoke(对象) 反射相当于一面镜子,这个方法很形象
method.invoke(o);
//获取公有的成员属性,不能直接获取私有成员,需要通过转化获取
Field age = aClass.getField("age");
//Filed 返回类的属性字段
System.out.println(age);
// 获取构造器,通过只能参数个数和类型.class来获取构造器
Constructor<?> constructor = aClass.getConstructor();// 无参构造器
System.out.println(constructor);
//有参构造
// 注意八大基本数据类型,不是.class,而是.TYPE
Constructor<?> constructor1 = aClass.getConstructor(Double.TYPE, String.class);
System.out.println(constructor1);
}
获取类的结构信息
基本api
@Test
public static void api01() throws ClassNotFoundException {
//获取类对象
Class<?> PersonClass = Class.forName("com.hly.class_.Person");
// 获取类的public属性,包括本类和父类
Field[] fields = PersonClass.getFields();
for (Field field : fields) {
System.out.println("该类和父类的所有公有属性="+field.getName());
}
// 获取本类所有属性
Field[] declaredFields = PersonClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println("本类的所有属性="+declaredField.getName());
}
// 获取该类的public方法,包括父类
Method[] methods = PersonClass.getMethods();
for (Method method : methods) {
System.out.println("所有的公有方法="+method.getName());
}
// 本类的所有方法
Method[] declaredMethods = PersonClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println("所有的方法="+declaredMethod.getName());
}
// 获取本类的public构造器,不包括父类
Constructor<?>[] constructors = PersonClass.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println("public构造器="+constructor);
}
// 本类的所有构造器
Constructor<?>[] declaredConstructors = PersonClass.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println("所有的构造器="+declaredConstructor);
}
//获取本类的接口
Class<?>[] interfaces = PersonClass.getInterfaces();
for (Class<?> anInterface : interfaces) {
System.out.println("接口="+anInterface.getName());
}
// 获取本类的接口
Annotation[] annotations = PersonClass.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println("注解="+annotation);
}
}
}
class A{
public int Ajob;
public void am1(){};
}
interface IA{}
interface IB{}
//Person类
@Deprecated
class Person extends A implements IA,IB{
public String job;
private int age;
String name;
protected String sex;
public Person(){}
private Person(int age){}
Person(String name){}
protected Person(String job,String sex){}
public String m1(int age){return null;}
private String m2(String name){return null;}
void m3(){}
protected void m4(){}
}
Filed
//获取类对象
Class<?> PersonClass = Class.forName("com.hly.class_.Person");
// 修饰符: 默认 0 public 1 private 2 protected 4 final 4 static 8
// 组合类型为 对应相加
Field[] declaredFields = PersonClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println("本类的所有属性="+declaredField.getName()+" 修饰符= "+declaredField.getModifiers()+
" 类型="+declaredField.getType());
}
Method
// 本类的所有方法
Method[] declaredMethods = PersonClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println("方法名="+declaredMethod.getName()+" 修饰符="+declaredMethod.getModifiers()
+"方法返回类型="+declaredMethod.getReturnType());
Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
System.out.println("该方法的参数列表:");
for (Class<?> parameterType : parameterTypes) {
System.out.println(parameterType.getName());
}
}
Constructor
// 构造器
Constructor<?>[] declaredConstructors = PersonClass.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println("所有的构造器="+declaredConstructor+" 修饰符="+declaredConstructor.getModifiers()
);
System.out.println("形参列表:");
Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();
for (Class<?> parameterType : parameterTypes) {
System.out.println(parameterType.getName());
}
}
爆破获取类的结构信息
Filed
public class ReflectFiled {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
Class<?> aClass = Class.forName("com.hly.reflection.Boss");
Object o = aClass.newInstance();
// 获取公有属性
Field name = aClass.getField("name");
// 设置属性
name.set(o,"hly");
System.out.println(o);
//获取私有属性
Field age = aClass.getDeclaredField("age");
//爆破
age.setAccessible(true);
age.set(o,19);
System.out.println(o);
//如果是static,则对象可以为null,或者是类的对象实例
Field sex = aClass.getDeclaredField("sex");
sex.setAccessible(true);
sex.set(null,"女");
System.out.println(o);
}
}
class Boss{
private int age;
public String name;
private static String sex;
public Boss(){};
@Override
public String toString() {
return "Boss{" +
"age=" + age +
", name='" + name + '\'' +
'}'+"sex="+sex;
}
}
Method
- 与属性操作类似
- aClass.getDeclaredMethod("xx方法名",参数列表.class);
反射机制
反射优点和缺点
- 优点:可以动态的创建和使用对象(也是框架底层核心),使用灵活,没有反射机制,框架技术就失去底层支撑
- 缺点:使用反射基本是解释执行,对执行速度有影响
优化
Field、Method、Constructor通过设置setAccessible()为true可以关闭访问执行时安全检测,提高执行速度.默认为false,即开启检测。提高不是很明显。