在 Java 语言 中,反射是用的比较多的,反射就是借助于 Class 对象 来获取类的结构,获取到我们想要的关于这个类的任何信息,比如构造方法,属性和方法。
我们先定义一个被操作的类,PersonForClass
package com.haicoder.net.cls;
public class PersonForClass {
private Integer age;
private String name;
public String color;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public PersonForClass() {
}
public PersonForClass(Integer age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "PersonForClass{" +
"name=" + name +
", age='" + age + '\'' +
'}';
}
}
package com.haicoder.net.cls;
import java.lang.reflect.Constructor;
public class ClassTest {
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
Class<?> constructClass = null;
try {
constructClass = Class.forName("com.haicoder.net.cls.PersonForClass");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
//获取全部构造方法,构造方法的顺序与代码里面的顺序一致
Constructor<?> cons[] = constructClass.getConstructors();
for (int i = 0; i < cons.length; i++) {
System.out.println("构造方法有:" + cons[i]);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果如下:
通过 getConstructors 方法,我们可以获取到被 public 修饰的构造方法。如果想获取全部的构造方法,并且没有权限的可以使用 getDeclaredConstructors 方法。
package com.haicoder.net.cls;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class ClassTest {
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
Class<?> class1 = null;
try {
class1 = Class.forName("com.haicoder.net.cls.PersonForClass");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
//获取全部构造方法,构造方法的顺序与代码里面的顺序一致
Field fields[] = class1.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Class<?> fType = fields[i].getType();
int modifier = fields[i].getModifiers();
String author = Modifier.toString(modifier);
System.out.print("属性名称:" + fields[i].getName());
System.out.print(" 属性权限:" + author);
System.out.print(" 属性类型:" + fType.getName());
System.out.println("");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果如下
我们使用了 getDeclaredFields 获取了所有的权限的属性信息,如果我们使用 getFields 只能获取到 public 修饰的属性。
package com.haicoder.net.cls;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class ClassTest {
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
Class<?> class1 = null;
try {
class1 = Class.forName("com.haicoder.net.cls.PersonForClass");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
Method[] methods = class1.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
Method tmpMethod = methods[i];
System.out.print("方法权限:" + Modifier.toString(tmpMethod.getModifiers()));
System.out.print(" 方法名称:" + tmpMethod.getName());
Class<?>[] paramTypes = tmpMethod.getParameterTypes();
System.out.print("(");
for (int j = 0; j < paramTypes.length; j++) {
System.out.print("" + paramTypes[j].getName() + " arg" + j);
}
System.out.print(")");
System.out.println("");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果如下:
获取方法的方式有 getDeclaredMethods 和 getMethods 方法。getMethods 只能获取到类里面是 public 修饰的方法,getDeclaredMethods 可以获取到所有的方法。同时我们可以拿到方法对应的名称,权限等等信息。
package com.haicoder.net.cls;
import java.lang.reflect.Method;
public class ClassTest {
public static void main(String[] args) {
System.out.println("嗨客网(www.haicoder.net)");
Class<?> class1 = null;
try {
class1 = Class.forName("com.haicoder.net.cls.PersonForClass");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
PersonForClass personForClass = (PersonForClass) class1.newInstance();
Method setAgeMethod = class1.getMethod("setAge", Integer.class);
Method setNameMethod = class1.getMethod("setName", String.class);
setAgeMethod.invoke(personForClass, 100);
setNameMethod.invoke(personForClass, "嗨客网");
System.out.println(personForClass.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果如下
我们可以通过 getMethod 里面传递方法名字和参数类型来确定我们需要获取的函数,然后通过调用函数的 invoke 方法将对象名称和数值传递进去,就相当于使用我们对象的方法了。
通过 Class 对象我们可以做很多事情,可以获取类里面的方法,属性和构造函数。反射就是借助于 Class 对象来对类进行一系列的操作。