反射机制
1.什么是反射?
反射可以理解为镜像,Java中可以把一个类映射成一个类对象,我们通过操作这个类对象,可以调用类的属性,方法,构造器。
2.如何理解java.lang.Class类
程序经过javac.exe命令后,会生成一个或者多个.class(字节码文件),接着我们使用java.exe命令对某个字节码文件进行解释运行,并且将类加载到内存中,
加载到内存中的类就叫做运行时类,就是java.lang.Class类的实例对象
3.如何获取Class类的实例对象(类对象)
注:如下三种方法获取的类对象都是同一个
public class ReflectTest01 {
public static void main(String[] args) throws ClassNotFoundException {
//获取Person类的类对象
//1.运行时类的class属性
Class personClass1 = Person.class;
//2.调用运行时类的实例对象的getclass()
Person p1 = new Person();
Class personClass2 = p1.getClass();
//3.调用Class类的静态方法
Class personClass3 = Class.forName("com.reflect.Person");
}
}
4.Java中哪些结构有类对象
注:只要加载到内存中,都会成为Class类的实例对象
1.class 2.interface 3.数组 4.枚举 5.注解 6.基本数据类型 7.void
5.读取配置文件
module下jdbc.properties的文件内容
username=root
password=123456
方式一: 该方法默认路径在module下
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
public class LoadPro {
public static void main(String[] args) throws IOException {
//路径默认在当前module下
File file = new File("jdbc.properties");
FileInputStream fileInputStream = new FileInputStream(file);
Properties properties = new Properties();
properties.load(fileInputStream);
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println("username:" + username + "--password:" + password);
}
}
方式二:利用classloader获取,该方法默认路径在module下的src下的resources目录中
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class LoadPro2 {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
ClassLoader classLoader = LoadPro2.class.getClassLoader();
//以流的形式读取文件
InputStream resourceAsStream = classLoader.getResourceAsStream("jdbc1.properties");
properties.load(resourceAsStream);
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(username + "---" + password);
}
}
6.创建运行时类的对象
public class ReflectTest02 {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Class personClass = Person.class;
/*
newInstance():调用此方法,创建对应的运行时类的对象,内部调用了运行时类的空参构造方法
运行此方法的要求:
1.运行时类必须提供一个的空的构造方法,权限默认是public
*/
Person person = personClass.newInstance();
System.out.println(person);
}
}
7.通过反射可以获取运行时类的完整结构
8.调用运行时类的指定结构(属性,方法,构造器)
实验所使用的自定义Person类
package com.reflect;
public class Person {
private String name;
public int age;
public Person() {
}
private Person(String name, int age) {
this.name = name;
this.age = age;
}
public void talk(){
System.out.println("i want to talk with you~");
}
private void sleep(){
System.out.println("i wanna to sleep !");
}
public String introduce(String nation){
System.out.println("i am "+ nation);
return nation;
}
public static void breath(){
System.out.println("i am breathing");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", 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;
}
}
1)操作属性
import java.lang.reflect.Field;
public class ReflectTest03 {
public static void main(String[] args) throws Exception {
//1.获取person类对象
Class> aClass = Class.forName("com.reflect.Person");
//2.创建运行时类的实例对象
Person person = (Person)aClass.newInstance();
//3.获取运行时类的指定的属性
//年龄
Field age = aClass.getDeclaredField("age");
//设置person对象的年龄为10
age.set(person, 10);
//名字
Field name = aClass.getDeclaredField("name");
//由于Person类中设置的访问权限为private,这里要设置是否可以修改为true
name.setAccessible(true);
//设置person对象的名字为Tom
name.set(person, "Tom");
//打印输出person对象
System.out.println(person);
}
}
2)操作方法
import java.lang.reflect.Method;
public class ReflectTest04 {
public static void main(String[] args) throws Exception {
//1.获取Person类对象
Class> personClass = Class.forName("com.reflect.Person");
//2.创建运行时类的实例对象
Person person = (Person)personClass.newInstance();
//3.操作运行时类的无参方法
Method talk = personClass.getDeclaredMethod("talk");
talk.setAccessible(true);
talk.invoke(person);
//4.操作运行时类的有参方法,并获取返回值
Method introduce = personClass.getDeclaredMethod("introduce", String.class);
introduce.setAccessible(true);
String returnMessage = (String) introduce.invoke(person, "Chinese");
System.out.println(returnMessage);
//5.操作运行时类的静态方法
Method breath = personClass.getDeclaredMethod("breath");
breath.setAccessible(true);
breath.invoke(Person.class);
}
}
3)操作构造器
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflectTest05 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class> personClass = Class.forName("com.reflect.Person");
//1.无参构造器创建运行时类对象
Person person1 = (Person) personClass.newInstance();
//2.有参构造器创建运行时类对象
Constructor> declaredConstructor = personClass.getDeclaredConstructor(String.class, int.class);
declaredConstructor.setAccessible(true);
Person tony = (Person) declaredConstructor.newInstance("Tony", 20);
System.out.println(person1 + "----" + tony);
}
}
来源:oschina
链接:https://my.oschina.net/u/4238564/blog/4794831