JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
反射之中包含了一个「反」字,所以想要解释反射就必须先从「正」开始解释。
一般情况下,我们使用某个类时必定知道它是什么类,是用来做什么的。于是我们直接对这个类进行实例化,之后使用这个类对象进行操作。
如:
Phone phone = new Phone(); //直接初始化,「正射」
phone.setPrice(4);
上面这样子进行类对象的初始化,我们可以理解为「正」。
而反射则是一开始并不知道我要初始化的类对象是什么,自然也无法使用 new 关键字来创建对象了。
这时候,我们使用 JDK 提供的反射 API 进行反射调用:
Class clz = Class.forName("com.xxp.reflect.Phone");
Method method = clz.getMethod("setPrice", int.class);
Constructor constructor = clz.getConstructor();
Object object = constructor.newInstance();
method.invoke(object, 4);
上面两段代码的执行结果,其实是完全一样的。但是其思路完全不一样,第一段代码在未运行时就已经确定了要运行的类(Phone),而第二段代码则是在运行时通过字符串值才得知要运行的类(com.xxp.reflect.Phone
)。
所以说什么是反射?反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。
Class.forName("类全名")
Class c1 = Class.forName(“java.lang.String”);
类名.class
Class c2 = String.class;
对象.getClass()
getClass()
方法来获取String str = new String("Hello");
Class c3 = str.getClass();
使用:
创建Person对象
package junit.reflects;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = 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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
主程序:
package junit.reflects;
public class Demo {
public static void main(String[] args) throws Exception {
/*
1.Class.forName("类全名")
2.类名.class
3.对象.getClass()
*/
//1.Class.forName("类全名")
Class c1 = Class.forName("junit.reflects.Person");
System.out.println(c1);
//2.类名.class
Class c2 = Person.class;
System.out.println(c2);
//3.对象.getClass()
Person person = new Person();
Class c3 = person.getClass();
System.out.println(c3);
}
}
Field[] getFields() 获取所有public修饰的成员变量
Field getField(String name) 获取指定名称的public修饰的成员变量
Field[] getDeclareFields() 获取所有的成员变量
Field getDeclaredField(String name) 获取指定的成员变量
具体使用:
创建DemoPersion
对象
package junit.reflects;
public class DemoPerson {
private String name01;
public String name02;
String name03;
protected String name04;
public String name05;
public DemoPerson() {
}
public DemoPerson(String name01, String name02, String name03, String name04, String name05) {
this.name01 = name01;
this.name02 = name02;
this.name03 = name03;
this.name04 = name04;
this.name05 = name05;
}
public String getName01() {
return name01;
}
public void setName01(String name01) {
this.name01 = name01;
}
public String getName02() {
return name02;
}
public void setName02(String name02) {
this.name02 = name02;
}
public String getName03() {
return name03;
}
public void setName03(String name03) {
this.name03 = name03;
}
public String getName04() {
return name04;
}
public void setName04(String name04) {
this.name04 = name04;
}
public String getName05() {
return name05;
}
public void setName05(String name05) {
this.name05 = name05;
}
@Override
public String toString() {
return "DemoPerson{" +
"name01='" + name01 + '\'' +
", name02='" + name02 + '\'' +
", name03='" + name03 + '\'' +
", name04='" + name04 + '\'' +
", name05='" + name05 + '\'' +
'}';
}
}
其中的成员变量:
private String name01;
public String name02;
String name03;
protected String name04;
public String name05;
创建主程序获取DemoPersion
的成员变量
package junit.reflects;
import java.lang.reflect.Field;
import java.util.stream.Stream;
public class Demo03 {
public static void main(String[] args) throws Exception {
//1.创建Class类对象
Class c1 =DemoPerson.class;
//2.通过Class对象获取DemoPerson类的成员变量
//getFields()获取所有public修饰的成员变量 name02 name05
Field[] s1 = c1.getFields();
//getField()获取指定public修饰的成员变量 name05
Field s2 = c1.getField("name05");
//getDeclareFields()获取所有成员变量 name01 name02 name03 name04 name05
Field[] s3 = c1.getDeclaredFields();
//getDeclareField()获取指定成员变量 name04
Field s4 = c1.getDeclaredField("name04");
Stream.of(s1).forEach(System.out::println);
System.out.println("===========================");
System.out.println(s2);
System.out.println("===========================");
Stream.of(s3).forEach(System.out::println);
System.out.println("===========================");
System.out.println(s4);
}
}
Constructor[] getConstructors();//无参构造
Constructor[] getConstructors(参数1类型.class,参数2类型.class...);//含参构造
Constructor getConstructor();
Constructor getConstructor(参数1类型.class,参数2类型.class...);
Constructor[] getDeclaredConstructors();
Constructor[] getDeclaredConstructors(参数1类型.class,参数2类型.class...);
Constructor getDeclaredConstructor();
Constructor getDeclaredConstructor(参数1类型.class,参数2类型.class...);
Method[] m3 = c1.getMethods();
Method m4 = c1.getMethod(String "方法名",方法参数1类型.class,方法参数2类型.class...);
Method[] m3 = c1.getDeclaredMethods();
Method m4 = c1.getDeclaredMethod(String "方法名",方法参数1类型.class,方法参数2类型.class...);
Srting getName();
构造方法.newInstance
package junit.reflects;
import java.lang.reflect.Constructor;
public class Demo02 {
public static void main(String[] args) throws Exception {
//创建Class对象
Class c1 = DemoPerson.class;
//创建含参构造
Constructor con01 = c1.getConstructor(String.class, String.class, String.class, String.class, String.class);
//使用newInstance创建对象,添加参数
Object obj = con01.newInstance("1号","2号","3号","4号","5号");
System.out.println(obj);
}
}
class类名.getDeclaredConstructor().newInstance
class类名.newInstance
(已过时)成员变量.get(类)
成员变量.set(类,值)
成员变量.setAccessible(true)
成员变量:
private String name01;
public String name02;
String name03;
protected String name04;
public String name05;
主程序:
package junit.reflects;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.stream.Stream;
public class Demo03 {
public static void main(String[] args) throws Exception {
//1.创建Class类对象
Class c1 = DemoPerson.class;
//2.通过Class对象获取DemoPerson类的成员变量
//getField()获取指定public修饰的成员变量 name05
Field s1 = c1.getField("name05");
//getDeclareField()获取指定成员变量 name04
Field s2 = c1.getDeclaredField("name04");
//创建构造方法
Constructor con = c1.getConstructor();
Object obj = con.newInstance();
//使用get与set获取和设置成员变量的值
s1.set(obj,"5号成员");
System.out.println(s1);
System.out.println(s1.get(obj));
s2.setAccessible(true);//protected保护的成员变量,使用暴力反射
s2.set(obj,"4号成员");
System.out.println(s2);
System.out.println(s2.get(obj));
}
}
获取的成员方法.invoke(类,成员方法参数1,成员方法参数2....)
类中的成员方法截取:
public void method01(String name,int age){
System.out.println("姓名:"+name+".年龄:"+age);
}
主程序:
package junit.reflects;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Demo01 {
public static void main(String[] args) throws Exception {
Class c1 = DemoPerson.class;
Method m1 = c1.getMethod("method01", String.class, int.class);
Constructor con = c1.getConstructor();
Object obj = con.newInstance();
m1.invoke(obj,"张三",12);
}
}