java 反射

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.Date;

class PrivateClass {
public String name;
private int age;

private PrivateClass(String name, int age) {
this.name = name;
this.age = age;
}

public PrivateClass(String name) {
this.name = name;
}

private PrivateClass(int age) {
this.age = age;
}

private PrivateClass() {}

private void show() {
System.out.println("姓名:" + name + "\t" + "年龄:" + age);
}
public String getName() {
return name;
}
public int getAge() {
return age;
}

public void showName(String name) {
System.out.println("您输入的名字是:" + name);
}

private static void showAge(int age) {
System.out.println("您输入的年龄是:" + age);
}
}

public class ReflectTest {
/**
* Class类是Reflection API中的核心类,它有以下方法
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes参数指定方法的参数类型。
getConstrutors():获得类的public类型的构造方法。
getConstrutor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象()。
注:Construtor也有newInstance(),而且私有的构造方法使用这种方式可以获得构造,需要事先蛇这Construtor.setAccessible(true);
*/
static void testDeclared() throws Exception {
// 获取Student的Class对象
Class<?> clazz = Class.forName("PrivateClass");

System.out.println("getDeclaredFields方法获取所有属性 ->>");
Field[] fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
// 打印属性信息,包括访问控制修饰符,类型及属性名
System.out.println(fields[i]);
System.out.println("修饰符:" + Modifier.toString(fields[i].getModifiers()));
System.out.println("类型:" + fields[i].getType());
System.out.println("属性名:" + fields[i].getName());
}

System.out.println("getDeclaredMethods方法获取该类中的所有方法 ->>");
Method[] methods = clazz.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
// 打印方法签名
System.out.println(methods[i]);
System.out.println("修饰符:" + Modifier.toString(methods[i].getModifiers()));
System.out.println("方法名:" + methods[i].getName());
System.out.println("返回类型:" + methods[i].getReturnType());
// 获取方法的参数对象
Class<?>[] parameterTypes = methods[i].getParameterTypes();
for (int j = 0; j < parameterTypes.length; j++) {
System.out.println("参数类型:" + parameterTypes[j]);
}
}

System.out.println("获取所有的构造方法 ->>");
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
for (int i = 0; i < constructors.length; i++) {
Constructor<?> constructor = constructors[i];
System.out.println("构造方法:" + constructor);
System.out.println("修饰符:" + Modifier.toString(constructor.getModifiers()));
System.out.println("是否可访问私有参数:" + constructor.isAccessible());
constructor.setAccessible(true); // 得到私有访问权限,如果不设置,则无法实例化对象
System.out.println("是否可访问私有参数:" + constructor.isAccessible());
// 输出构造器参数的全部类型
Type types[] = constructor.getGenericParameterTypes();
System.out.println("构造参数:");
for (int j = 0; j < types.length; j++) {
System.out.print(types[j] + "   ");
}
}
}

static void testSetAndCall() throws Exception {
Class<?> clazz = PrivateClass.class;//预先知道该类
Constructor<?> constructor0 = clazz.getDeclaredConstructor();
System.out.println("获取无参构造方法:" + constructor0);
//通过设置可触及私有参数,这种方式可以通过jdk参数设置关闭此功能从而保护类的私有参数,但通常没有必要
constructor0.setAccessible(true);
PrivateClass privateClass = (PrivateClass) constructor0.newInstance();//这种方式能创建私有构造方法类
// PrivateClass privateClass = (PrivateClass) clazz.newInstance();//这种方式默认调用无参构造函数,所以不能创建私有构造类的实例


//默认智能设置public的属性值
Field namefField = clazz.getField("name");//getField 方法 只能反射public方法
namefField.setAccessible(true);// 如果是私有的,这样可以对私有属性赋值
namefField.set(privateClass, "张三");
System.out.println(privateClass.getName());

Field agefField = clazz.getDeclaredField("age");//getDeclaredField 反射所有方法
agefField.setAccessible(true);// 这样可以对私有属性赋值
agefField.set(privateClass, 100);
System.out.println(privateClass.getAge());

//执行公共方法
Method showNameMethod = clazz.getMethod("showName", String.class);
showNameMethod.invoke(privateClass, "李四");
//执行私有静态方法
Method showAgeMethod = clazz.getDeclaredMethod("showAge", int.class);
showAgeMethod.setAccessible(true);// 配置后可访问私有方法
//静态方法访问方式
showAgeMethod.invoke(privateClass, 2000);
showAgeMethod.invoke(clazz, 2000);
showAgeMethod.invoke(null, 2000);
showAgeMethod.invoke(String.class, 2000);//任意class
showAgeMethod.invoke(Date.class, 2000);//任意class

// 双参数构造
Constructor<?> constructor2 = clazz.getDeclaredConstructor(String.class, int.class);
System.out.println("获取双参数构造方法:" + constructor2);
//通过设置可触及私有参数,这种方式可以通过jdk参数设置关闭此功能从而保护类的私有参数,但通常没有必要
constructor2.setAccessible(true);
PrivateClass privateClass2 = (PrivateClass) constructor2.newInstance("王五", 110);//这种方式不能创建私有构造

//执行方法
// Method showmMethod = clazz.getMethod("show");//只能反射public
Method showmMethod = clazz.getDeclaredMethod("show");//可以反射private
showmMethod.setAccessible(true);// 配置后可访问私有方法
//第一个实例的方法
showmMethod.invoke(privateClass);
//第二个实例的方法
showmMethod.invoke(privateClass2);
}



public static void main(String[] args) throws Exception {
testDeclared();
testSetAndCall();
}

}

运行结果:

getDeclaredFields方法获取所有属性 ->>
public java.lang.String PrivateClass.name
修饰符:public
类型:class java.lang.String
属性名:name
private int PrivateClass.age
修饰符:private
类型:int
属性名:age
getDeclaredMethods方法获取该类中的所有方法 ->>
public int PrivateClass.getAge()
修饰符:public
方法名:getAge
返回类型:int
public void PrivateClass.showName(java.lang.String)
修饰符:public
方法名:showName
返回类型:void
参数类型:class java.lang.String
private static void PrivateClass.showAge(int)
修饰符:private static
方法名:showAge
返回类型:void
参数类型:int
private void PrivateClass.show()
修饰符:private
方法名:show
返回类型:void
public java.lang.String PrivateClass.getName()
修饰符:public
方法名:getName
返回类型:class java.lang.String
获取所有的构造方法 ->>
构造方法:private PrivateClass(java.lang.String,int)
修饰符:private
是否可访问私有参数:false
是否可访问私有参数:true
构造参数:
class java.lang.String   int   构造方法:public PrivateClass(java.lang.String)
修饰符:public
是否可访问私有参数:false
是否可访问私有参数:true
构造参数:
class java.lang.String   构造方法:private PrivateClass(int)
修饰符:private
是否可访问私有参数:false
是否可访问私有参数:true
构造参数:
int   构造方法:private PrivateClass()
修饰符:private
是否可访问私有参数:false
是否可访问私有参数:true
构造参数:
获取无参构造方法:private PrivateClass()
张三
100
您输入的名字是:李四
您输入的年龄是:2000
您输入的年龄是:2000
您输入的年龄是:2000
您输入的年龄是:2000
您输入的年龄是:2000
获取双参数构造方法:private PrivateClass(java.lang.String,int)
姓名:张三 年龄:100
姓名:王五 年龄:110

你可能感兴趣的:(java 反射)