反射
定义
反射机制是在运行状态中,对于任何一个类可以知道其所有的属性和方法(包括私有的),对于任何一个对象可以调用其所有的属性和方法(包括私有的),同时可以修改部分类型信息
反射起源
反射相关的类
类名 | 用途 |
---|
Class | 代表类的实体 | Field | 代表类的成员变量 | Method | 代表类的方法 | Constructor | 代表类的构造方法 |
class Person{
private String name = "James";
public int age = 36;
public Person() {
this.name = "Kobe";
this.age = 41;
}
private Person(String name, int age) {
this.name = name;
this.age = age;
}
private void BasketBall(){
System.out.println("Rusall Westbrook");
}
public void Swimming(){
System.out.println("Sun Yang");
}
private void FootBall(String str){
System.out.println(str);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
获得Class类的对象
- Class.forName("类的全路径名 (包名.类名) ")
forName()是Class类的静态方法,此方法可能会抛出异常 - 每一个类都有一个隐含的静态成员变量.class
- 使用类的普通方法getClass()(继承自Object)
先new一个类的对象,再调用getClass()方法 - 一个类只能对应一个Class类对象
public static void main(String[] args) {
Class c1 = null;
try{
c1 = Class.forName("Reflect.Person");
}catch (ClassNotFoundException e) {
e.printStackTrace();
}
Class c2 = Person.class;
Person person = new Person();
Class c3 = person.getClass();
System.out.println(c1 == c2);
System.out.println(c2 == c3);
}
创建对象
public static void reflectnewInstance() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Class c = Class.forName("Reflect.Person");
Person person = (Person) c.newInstance();
System.out.println(person);
}
反射私有的构造方法
getDeclaredConstructor(参数类型…)
方法 | 用法 |
---|
Constructor getConstructor(Class…<?> types) | 获取参数对应的公有构造方法 | Constructor getDeclaredConstructor(Class…<?> types) | 获取参数对应的构造方法(公有、私有都可以哦) | Constructor[ ] getConstructors() | 获取该类的所有的公有构造方法 | Constructor[ ] getDeclaredConstructors() | 获取该类所有的构造方法 |
public static void re_Pri_Con() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class c = Class.forName("Reflect.Person");
Constructor constructor = c.getDeclaredConstructor(String.class,int.class);
constructor.setAccessible(true);
Person person = (Person) constructor.newInstance("强爷",18);
System.out.println(person);
}
public static void re_Pub_Con() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class c = Class.forName("Reflect.Person");
Constructor constructor = c.getConstructor();
constructor.setAccessible(true);
Person person = (Person)constructor.newInstance();
System.out.println(person);
}
反射私有的成员变量
getDeclaredField(“指定成员变量的名字”) field.set(类的对象,修改的成员变量的内容);
方法 | |
---|
Field getField(String name) | 获取对应的公有成员变量 | Field getDeclaredField(String name) | 获取对应的成员变量(公有、私有) | Field[ ] getFields() | 获取所有的公有成员变量 | Field[ ] getDeclaredFields() | 获取所有的成员变量 |
public static void re_Pri_Field() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
Class c = Class.forName("Reflect.Person");
Person person = (Person) c.newInstance();
Field field = c.getDeclaredField("name");
field.setAccessible(true);
field.set(person,"Durant");
System.out.println(person);
String str = (String) field.get(person);
System.out.println("将私有属性修改为" + str);
}
反射私有的方法
getDeclaredMethod(“指定方法的名字”,参数类型…) invoke(类的对象,传入的参数)
方法 | |
---|
Method getMethod(String name, Class…<?> types) | 获取指定的公有方法 | Method getDeclaredMethod(String name, Class…<?> types) | 获取指定的方法(公有、私有) | Method[ ] getMethods() | 获取所有的公有方法 | Method[ ] getDeclaredMethods() | 获取所有的方法 |
public static void re_Pri_Method() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
Class c = Class.forName("Reflect.Person");
Person person = (Person) c.newInstance();
Method method = c.getDeclaredMethod("FootBall", String.class);
method.setAccessible(true);
method.invoke(person,"罗那尔多");
}
反射的优点:
- 对于任何一个类,可以直到它所有的属性和方法;对于任何一个对象可以调用它所有的属性和方法
- 增减程序的灵活性
- 反射已经应用于多个框架,Struts、Spring等
缺点
- 使用反射导致程序效率降低
- 反射绕过了源代码的技术,会带来维护问题
祝贺EDG3:2战胜DK登顶世界之巅 银龙重铸之日,骑士归来之时 重铸LPL荣光,我辈义不容辞
|