Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
public class Person {
private String name;
public int 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 Person(String name, int age) {
this.name = name;
this.age = age;
}
private Person(String name){
this.name = name;
}
public Person() {
System.out.println("调用person的空参构造");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
public void show(){
System.out.println("我是一个人");
}
private String showNation(String nation){
System.out.println("我的国籍是:" + nation);
return nation;
}
}
public class PersonTest {
public static void main(String[] args) throws Exception{
// 1. 实例化对象
Person person = new Person("tom",12);
// 通过对象调用属性方法
person.age = 10;
person.show();
System.out.println(person.toString());
System.out.println("************反射*************");
// 通过反射来创建对象(调用私有的方法)
Class clazz = Person.class;
Constructor conn = clazz.getDeclaredConstructor(String.class);
conn.setAccessible(true);
Person hong = (Person)conn.newInstance("hong");
System.out.println(hong.toString());
// 通过反射,调取对象的属性,方法
Field name = clazz.getDeclaredField("name");
name.setAccessible(true);
name.set(hong,"tbc");
System.out.println(hong);
Method show = clazz.getDeclaredMethod("showNation", String.class);
show.setAccessible(true);
String result = (String)show.invoke(hong, "中国");
System.out.println(result);
}
}
3. 获取Class的四种方式
public class ClassTest {
public static void main(String[] args) throws Exception{
// 1. 类.class:调用运行时类的属性
Class clazz1 = Person.class;
System.out.println(clazz1);
// 2. 通过运行时类的对象
Person p1 = new Person();
Class clazz2 = p1.getClass();
System.out.println(clazz2);
// 3. 调用Class的forName方法 这种使用得多
Class clazz3 = Class.forName("tbc.demo12.Person");
System.out.println(clazz3);
System.out.println(clazz1 == clazz2);
System.out.println(clazz1 == clazz3);
// 4. 使用类加载器
ClassLoader classLoader = ClassTest.class.getClassLoader();
Class clazz4 = classLoader.loadClass("tbc.demo12.Person");
System.out.println(clazz4);
System.out.println(clazz1 == clazz4);
}
}
4. 读取配置文件
public class ClassLoaderDemo2 {
public static void main(String[] args) throws Exception{
Properties pro = new Properties();
// 读取配置文件方式一:读取当前的module下的
// 读取配置文件方式二:读取src下的
ClassLoader classLoader = ClassLoaderDemo2.class.getClassLoader();
InputStream resourceAsStream = classLoader.getResourceAsStream("jdbc1.properties");
pro.load(resourceAsStream);
String username = pro.getProperty("username");
String password = pro.getProperty("password");
System.out.println(username);
System.out.println(password);
}
}
5. 类加载器
public class ClassLoaderDemo {
public static void main(String[] args) {
// 对于自定义类,使用系统类加载器加载
ClassLoader classLoader = ClassLoaderDemo.class.getClassLoader();
System.out.println(classLoader);// 这是系统类加载器
ClassLoader parent1 = classLoader.getParent();
System.out.println(parent1); // 扩展类加载器
ClassLoader parent2 = parent1.getParent();
// 引导类加载器加载java的核心类库,无法加载自定义类
System.out.println(parent2);// 获取不到引导类加载器
}
}
6. 有Class对象的类型
public class ClassDemo1 {
public static void main(String[] args) {
Class c1 = Object.class; // 类
Class c2 = Comparable.class; // 接口
Class c3 = String[].class; // String数组
Class c4 = int[][].class; // int数组
Class c5 = ElementType.class; // 枚举类型
Class c6 = Override.class; // 注解
Class c7 = int.class; // 基本数据类型
Class c8 = void.class; // void
Class c9 = Class.class; // Class
int[] a = new int[10];
int[] b = new int[100];
Class c10 = a.getClass(); // void
Class c11 = b.getClass(); // Class
// 只要数组的元素类型和纬度一样,就是同一个Class
System.out.println(c10 == c11);
}
}



