反射机制
反射是java动态语言的关键
反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法
package com.lxw.java1;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class RedlectionTest {
/*
反射之前
*/
@Test
public void test1(){
Person p1 = new Person("Tom",12);
p1.age = 10;
System.out.println(p1);
p1.show();
}
/*
关于java.lang.Class的理解
1.类的加载过程
javac.exe-->字节码文件.class文件,
接着java.exe解释运行,相当于把字节码文件加载到内存中,这个过程称为类的加载
加载进内存的类,称为运行时类,此时的运行时类,就作为Class的一个实例
2.Class的实例就对应着一个运行时的类
3.加载到内存的运行时类,会缓存一定的时间,在此时间内,可以通过不同方式获取运行时类
*/
/*
反射之后
*/
@Test
public void test2() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
Class<Person> personClass = Person.class;
Constructor<Person> constructor = personClass.getConstructor(String.class, int.class);
Person person = constructor.newInstance("Tom",12);
System.out.println(person.toString());
person.age = 15;
System.out.println(person);
person.show();
//调用属性
Field age = personClass.getDeclaredField("age");
age.set(person,250);
System.out.println(person);
//调用方法
Method show = personClass.getDeclaredMethod("show");
show.invoke(person);
//通过反射,可以调用Person类的私有结构。比如:私有的构造器,方法,属性
//调用私有的构造器
Constructor<Person> declaredConstructor = personClass.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);
Person person1 = declaredConstructor.newInstance("Jerry");
System.out.println(person1);
//调用私有属性
Field name = personClass.getDeclaredField("name");
name.setAccessible(true);
name.set(person1,"ydd");
System.out.println(person1);
//调用私有方法
Method showNation = personClass.getDeclaredMethod("showNation", String.class);
showNation.setAccessible(true);
String nation = (String)showNation.invoke(person1, "中国");
System.out.println(nation);
}
/*
获取Class的实例的方式
*/
@Test
public void test3() throws ClassNotFoundException {
//方式一:调用运行时类的属性.class
Class<Person> personClass = Person.class;
System.out.println(personClass);
//方式二:通过运行时类的对象获取
Person p1 = new Person();
Class<? extends Person> p1Class = p1.getClass();
System.out.println(p1Class);
//方式三:调用Class的静态方法:forName()************使用较多*************
Class<?> aClass = Class.forName("com.lxw.java1.Person");
System.out.println(aClass);
System.out.println(personClass == p1Class);
System.out.println(personClass == aClass);
//方式四:使用类的加载器
ClassLoader classLoader = RedlectionTest.class.getClassLoader();
Class<?> aClass1 = classLoader.loadClass("com.lxw.java1.Person");
System.out.println(aClass1);
}
}
package com.lxw.java1;
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 反射
* 操作运行时类的属性
* 操作运行时类的方法
*/
public class ReflectionTest {
/*
如何操作运行时类中的指定属性
*/
@Test
public void test1() throws Exception{
Class<Person> personClass = Person.class;
//创建运行时类的对象newInstance()
Person person = personClass.newInstance();
//1.getDeclaredField()获取运行时类中指定变量名的属性
Field name = personClass.getDeclaredField("name");
//2.保证属性可访问setAccessible(true)
name.setAccessible(true);
//3.获取设置指定对象的此属性值
name.set(person,"ydd");
System.out.println(person);
}
/*
操作运行时类的方法
*/
@Test
public void test2() throws Exception{
Class<Person> personClass = Person.class;
Person person = personClass.newInstance();
//1.获取某个方法getDeclaredMethod()
//方法名,形参列表
Method show = personClass.getDeclaredMethod("show", String.class);
//invoke()调用方法
//调用者,给形参赋值
//invoke()方法的返回值即为方法show的返回值
show.invoke(person,"China");
}
}
package com.lxw.java1;
public class Person {
private String name;
public int age;
public Person() {
}
private Person(String name) {
this.name = name;
}
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;
}
public void show(){
System.out.println("我是空show");
}
public void show(String s){
System.out.println(s);
}
private String showNation(String nation){
return nation;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
评论区