一、如何获取一个类:
1、Class cls = Class.forName("java.lang.String");
2、String str = "zhangsan";
Class cls = str.getClass();
3、Class cls = String.class; //注意String.class的class是小写的C
二、利用反射访问类中的字段:
1、getFields()方法:
获得某个类中所有的公有属性(public)的字段,包括这个类的父类中的public属性字段。
2、getDeclaredFields()方法:
获得某个类中所有属性的字段(public、private、protect),但是不包括这个类的父类。
代码演示:
现有一个 PersonalInfo类 和一个 StuInfo类,StuInfo类继承PersonalInfo类并重写了 toString()方法:
class PersonInfo{
public String name = "zhangsan";
}
class StuInfo extends PersonInfo{
public int age;
private int money;
@Override
public String toString() {
return "StuInfo{" +
"name=" + name +
", money=" + money +
'}';
}
}
(1) 使用 getFields()方法获取 类StuInfo中的公有成员变量age和其父类中的公有成员变量name:
Class stiClass = StuInfo.clas;
// 获取public字段"age":
System.out.println(stiClass.getField("age"));
// 获取继承的public字段"name":
System.out.println(stiClass.getField("name"));
(2) 使用 getDeclared()方法获取 类StuInfo中的私有成员变量money:
Class stiClass = StuInfo.class;
System.out.println(stiClass.getDeclaredField("money"));
(3) 使用 newInstance()方法,利用反射创建实例化对象:
Field name = stiClass.getField("name");
System.out.println(name.get(stiClass.newInstance()));
(4) 利用setAccessible()方法设置私有属性money的值:
Field money = stiClass.getDeclaredField("money");
money.setAccessible(true);
money.set(stuInfo,2333333);
//Java 的 setAccessible 是一个访问控制方法,它可以用来控制 Java 中类的访问权限。如果某个成员变量被声明为 private 或 protected,普通的程序是不能访问它的。但是如果使用 setAccessible 方法将其设置为 true,程序就可以访问该变量了。
三、利用反射获取类中的方法:
1、Method getMethod(name, 参数类型):获取当前类中的某个public方法,包括其父类中的方法。
2、Method getDeclaredMethod(name, 参数类型):获取某个类中的某个任意属性的方法(public、private、protect),但不包括其父类中的方法。
3、Method[] getMethods():获取当前类中的所有public方法。
4、Method[] getDeclaredMethods():获取当前类中任意属性的所有方法,但不包括其父类中的方法。
代码演示:
public class reflectTest01 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
String name = "zhangsan";
Method substring = String.class.getMethod("substring", int.class);
System.out.println(substring.invoke(name, 3));
}
}
//输出结果为 ngsan
Obj参数为null,代码如下:
Method m = Integer.class.getMethod("parseInt", String.class);
System.out.println(m.invoke(null, "3"));
//输出结果为 3
四、获取构造方法:
1、getConstructor(构造方法的参数类型1、构造方法的参数类型2、...):获取当前类中某个public属性的构造方法。
2、getDeclaredConstructor(构造方法的参数类型1、构造方法的参数类型2、...):获取当前类中某个任意属性的构造方法。
3、getConstructors(): 获取当前类中所有public属性的无参数构造方法。
4、getDeclaredConstructors():获取当前类中所有任意属性的无参数构造方法。
注:调用非public属性的构造方法时,必须要先通过 setAccessible(true)设置允许访问,setAccessible(true)可能会失败。
五、java反射进行命令执行:
java语句进行命令执行:
Windows:java.lang.Runtime.getRuntime().exec("cmd /c start calc");
MacOS:java.lang.Runtime.getRuntime().exec("open -na Calculator");
java反射语句进行命令执行:
Windows:
Class.forName("java.lang.Runtime").getMethod("getRuntime").invoke(null)
.getClass().getMethod("exec", String.class).invoke(Runtime.getRuntime(),"cmd /c start calc");
MacOS:
Class.forName("java.lang.Runtime").getMethod("getRuntime").invoke(null)
.getClass().getMethod("exec", String.class).invoke(Runtime.getRuntime(),"open -na Calculator");
六、修改被final关键字修饰的变量:
在 javaReflection.User 中,设有 final修饰的整数变量 finalNumber = 666:
通过下文代码即可进行修改并打印:
public class reflectTest01 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException, ClassNotFoundException, InstantiationException, NoSuchFieldException {
Class userClass = Class.forName("javaReflection.User");
User user = (User)userClass.newInstance();
Field field = userClass.getDeclaredField("finalNumber");
field.setAccessible(true);
field.setInt(user, 100);
System.out.println(field.get(user));
}
}
//输出结果:
//无参数构造方法执行
//100
标签:反射,Java,name,构造方法,class,public,类中,String
From: https://www.cnblogs.com/kgty/p/18429126