反射定义
百度定义:Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
自己的理解:反射就是把类的各个成分映射成对象,构造函数、变量、函数都映射成对象进行操作。
反射的基本用法
Man类:
public class Man {
public Man() {
System.out.println("public---无参构造函数---");
}
private Man(int age){
this.age = age;
System.out.println("private---有参构造函数---age=" + age);
}
public Man(int age, String name) {
this.age = age;
this.name = name;
System.out.println("public---有参构造函数---:age=" + age + "---name=" + name);
}
private int age;
public String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private void message(String name,int time) {
System.out.println("提供马杀鸡服务:" + name + ",时间:" + time + "分钟");
}
}
1.构造方法
public class MyClass {
public static void main(String[] args) {
try {
Class clz = Class.forName("com.miss.lib.bean.Man");
// 获取所有public构造函数
System.out.println("----获取公有构造函数---");
Constructor[] constructors = clz.getConstructors();
for (Constructor c : constructors) {
System.out.println(c);
}
// 获取所有构造函数(public、private)
System.out.println("----获取所有构造函数---");
Constructor[] declaredConstructors = clz.getDeclaredConstructors();
for (Constructor c : declaredConstructors) {
System.out.println(c);
}
// 获取公有、无参构造函数
System.out.println("----获取公有、无参构造函数---");
Constructor constructor = clz.getConstructor();
System.out.println(constructor);
// 调用构造方法
Object o = constructor.newInstance();
// 获取私有、有参构造函数---后面填的是参数列表
System.out.println("----获取私有、有参构造函数---");
Constructor priConstructor = clz.getDeclaredConstructor(int.class);
System.out.println(priConstructor);
// 调用构造方法,可访问
priConstructor.setAccessible(true);
Object obj = priConstructor.newInstance(24);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
测试输出
> Task :lib:MyClass.main()
----获取公有构造函数---
public com.miss.lib.bean.Man(int,java.lang.String)
public com.miss.lib.bean.Man()
----获取所有构造函数---
public com.miss.lib.bean.Man(int,java.lang.String)
private com.miss.lib.bean.Man(int)
public com.miss.lib.bean.Man()
----获取公有、无参构造函数---
public com.miss.lib.bean.Man()
public---无参构造函数---
----获取私有、有参构造函数---
private com.miss.lib.bean.Man(int)
private---有参构造函数---age=24
BUILD SUCCESSFUL in 397ms
2.获取成员变量并调用
public class Fields {
public static void main(String[] args) {
try {
Class clz = Class.forName("com.miss.lib.bean.Man");
Object obj = clz.newInstance();
System.out.println("-------------获取所有公有变量-------------");
Field[] fields = clz.getFields();
for (Field f : fields) {
System.out.println(f);
}
System.out.println("-------------获取所有变量-------------");
Field[] declaredFields = clz.getDeclaredFields();
for (Field f : declaredFields) {
System.out.println(f);
}
System.out.println("-------------获取公有变量-------------");
Field field = clz.getField("name");
// 为对象设置值
field.set(obj,"二狗子");
Man man = (Man) obj;
System.out.println("man.name=" + man.name);
System.out.println("-------------获取私有变量-------------");
Field declaredField = clz.getDeclaredField("age");
// 解除私有限定
declaredField.setAccessible(true);
declaredField.set(obj,26);
System.out.println("man.getAge=" + man.getAge());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
测试输出
> Task :lib:Fields.main()
public---无参构造函数---
-------------获取所有公有变量-------------
public java.lang.String com.miss.lib.bean.Man.name
-------------获取所有变量-------------
private int com.miss.lib.bean.Man.age
public java.lang.String com.miss.lib.bean.Man.name
-------------获取公有变量-------------
man.name=二狗子
-------------获取私有变量-------------
man.getAge=26
BUILD SUCCESSFUL in 385ms
3.获取成员方法并调用
public class Methods {
public static void main(String[] args) {
try {
Class clz = Class.forName("com.miss.lib.bean.Man");
Object obj = clz.newInstance();
System.out.println("--------------获取所有公有函数--------------");
Method[] methods = clz.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("--------------获取所有公有函数--------------");
Method[] declaredMethods = clz.getDeclaredMethods();
for (Method method : declaredMethods) {
System.out.println(method);
}
System.out.println("--------------获取公有函数并调用--------------");
Method method = clz.getMethod("setName", String.class);
System.out.println(method);
method.invoke(obj, "二狗子");
Man man = (Man) obj;
System.out.println("man.name=" + man.name);
System.out.println("--------------获取私有函数并调用--------------");
Method declaredMethod = clz.getDeclaredMethod("message", String.class, int.class);
System.out.println(declaredMethod);
// 解除私有限定
declaredMethod.setAccessible(true);
declaredMethod.invoke(obj, "二狗子",60);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
测试输出
--------------获取所有公有函数--------------
public java.lang.String com.miss.lib.bean.Man.getName()
public void com.miss.lib.bean.Man.setName(java.lang.String)
private void com.miss.lib.bean.Man.message(java.lang.String,int)
public void com.miss.lib.bean.Man.setAge(int)
public int com.miss.lib.bean.Man.getAge()
--------------获取公有函数并调用--------------
public void com.miss.lib.bean.Man.setName(java.lang.String)
man.name=二狗子
--------------获取私有函数并调用--------------
private void com.miss.lib.bean.Man.message(java.lang.String,int)
提供马杀鸡服务:二狗子,时间:60分钟
BUILD SUCCESSFUL in 395ms
2 actionable tasks: 2 executed
21:39:24: Task execution finished 'Methods.main()'.
假装有总结
- 获取私有的基本都是 getDeclared–,使用时一定要解除私有权限!
- 参数列表一定要注意
GitHub
代码在lib包下