public class Test {
//反射之前,对于Person的操作
public void test(){
Person person=new Person("Tom",12);
//在person类外部,不可以通过person类的对象调用内部的私有结构
person.getAge();
}
@org.junit.Test
//有反射之后,对于person的操作
public void test1() throws Exception {
Class c = Person.class;
//-------------------------------------------------------------------
//1,通过反射创建类对象
Constructor constructor = c.getConstructor(String.class, int.class);
Object sam = constructor.newInstance("Sam", 13);
Person person= (Person) sam;
System.out.println(person);
//-------------------------------------------------------------------
//2,通过反射,调用对象指定的属性,方法
//调用属性(获得属性名叫 name的属性)
Field name = c.getDeclaredField("name");
name.set(person,"Tom");
System.out.println(person);
//调用方法
Method show = c.getDeclaredMethod("show");
show.invoke(person);
//-------------------------------------------------------------------
//3,通过反射,可以调用类的私有结构。比如:私有属性,私有构造器,私有方法(暴力反射)
// 调用私有构造器
Constructor constructor1 = c.getDeclaredConstructor();
constructor1.setAccessible(true);
Person p = (Person) constructor1.newInstance();
System.out.println(p);
//调用私有属性
Field age = c.getDeclaredField("age");
age.setAccessible(true);
age.set(p,15);
System.out.println(p);
//调用私有方法
Method showAge = c.getDeclaredMethod("showAge");
showAge.setAccessible(true);
showAge.invoke(p);
}
}
@org.junit.Test
public void testClassLoader(){
//对于自定义类,使用系统类加载器进行加载
ClassLoader classLoader=Person.class.getClassLoader();
System.out.println(classLoader);
//调用系统类加载器的getParent():获取扩展类加载器
ClassLoader parent = classLoader.getParent();
System.out.println(parent);
//调用扩展类加载器的getParent():无法获取引导类加载器
//引导类加载器主要负责加载java的核心类库,无法加载自定义类的
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);
}
获取Class实例的方式
@org.junit.Test
public void test2() throws ClassNotFoundException {
/**
* 获取Class实实例的方式
*/
//方式1:调用运行时类的属性:.class
Class<Person> personClass = Person.class;
//方式2:通过运行时类的对象,调用getClass()
Person person=new Person();
Class aClass = person.getClass();
//方式3:调用Class的静态方法:forName(String classPath)
Class people = Class.forName("abc.People");//路径
//方式4:使用类的加载器:ClassLoader
ClassLoader classLoader = People.class.getClassLoader();
Class aClass1 = classLoader.loadClass("abc.People");
}
读取配置文件
@org.junit.Test
public void test4() throws IOException {
Properties properties=new Properties();
//读取配置文件一:
//文件默认在module下
// FileInputStream fileInputStream=new FileInputStream("people.properties");
// properties.load(fileInputStream);
//读取配置文件而:使用ClassLoader
//配置文件默认识别为module的src下
ClassLoader classLoader=People.class.getClassLoader();
InputStream resourceAsStream = classLoader.getResourceAsStream("people.properties");
properties.load(resourceAsStream);
String user = properties.getProperty("user");
System.out.println(user);
}
通过反射创建对应的运行时类的对象
@org.junit.Test
public void test5() throws IllegalAccessException, InstantiationException {
Class c=Person.class;
/*
newInstance():调用此方法,创建对应的运行时类的对象。内部调用运行时类的空参构造器
在javabean中要求提供一个空参构造器,原因;
1,便于通过反射,创建运行时类的对象
2,便于子类继承此运行时类时,默认调用super()时,保证父类有此构造器
*/
Object o = c.newInstance();
System.out.println(o);
}
获取属性结构
@org.junit.Test
public void test6(){
/**
* 获取属性结构:
* 属性(可以获得父类的public),方法(可以获得父类的public),权限修饰符,数据类型,变量名,注解,返回值类型,形参列表,抛出的异常
* 获取构造器结构,获取运行时类的父类(也可以获取带泛型的父类),获取泛型类型,获取接口,获取运行时类所在的包
* 以下就不举例太多了
*/
Class c=Person.class;
//getFields():获取当前运行时类及其父类中声明为public访问权限的属性
Field[] fields=c.getFields();
for(Field i:fields){
System.out.println(i);
}
//getDeclaredFields():获取当前运行时类中声明的所有属性(不包含父类中声明的属性)
Field[] declaredFields = c.getDeclaredFields();
for(Field i:declaredFields){
System.out.println(i);
}
}