使用反射机制实例化对象
java代码写一遍,在不改变java源码的情况下,可以创建不同的类
使用newInstance方法
Class c = Class.forName("java.lang.String");
Object obj = c.newInstance(); // java9 以后过时
newInstance()
会调用无参数构造方法,所以类里面最好保持无参构造方法
获取类路径下的绝对路径
FileReader reader = new FileReader("chapter25/classinfo.properties");
该方法的缺点:移植性差.在IDEA中默认的当前路径是project的根
如果离开IDEA,换到其他位置,可能当前路径就不是project的根了.
注意:使用该方法的前提,是,该文件必须在类路径下. 类路径: src文件夹
// Thread.currentThread() 当前线程对象
// getContextClassLoader() 线程对象的方法,获取当前线程的类加载器
// getResource("classinfo.properties") 【获取资源】这是类加载器的方法,默认从类的根路径下加载资源
String path = Thread.currentThread().getContextClassLoader().getResource("classinfo.properties").getPath();
直接以流的形式返回
InputStream reader = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("路径");
Properties pro = new Properties();
pro.load(reader);
reader.close();
// 通过key获取value
String className = pro.getProperty("className");
java.util包下的资源绑定器
使用这个方法的时候,属性配置文件必须放到类路径下
限制:
- 文件必须直接放在类路径下(src目录下)
- 只能是properties文件
- 路径的时候只要文件名
ResourceBundle bundle = ResourceBundle.getBundle("db");
String className = bundle.getString("className");
获取Field
- getFields() 返回所有公开的属性 public 修饰的
- getDeclaredFields() 返回所有的属性
- getName() 返回属性的名字,getSimpleName
- getType() 返回属性的类型
- getModifiers() 返回属性的修饰符列表,返回int,如果要转化为字符串,则使用
Modifier.toString(int i)
```java public Class Student{ public String name; protected String address; private int age; boolean sex; }
Class studentClass = Class.forName(“com.liangwei.bean.Student”); Field[] fields = studentClass.getFileds(); // 返回数组 for(Field field : fields){ String name = field.getName(); // 返回名字,String Class fieldType = field.getType(); // 获取属性的名字,返回Class对象 String className = fieldType.getName();
}
<a name="roRrB"></a>
## 通过反射机制获取java对象的属性 **
使用`getDeclaredField` 只能访问public方法<br />使用setAccessible(True) 打破封装
```java
// 1. 获取类名
Class studentClass = Class.forName("com.liangwei.bean.Student");
// 2. 获取属性(通过名字获取)
Field nameField = studentClass.getDeclaredField("name");
// 私有属性,使用该语句可以打破封装
nameField.setAccessible(True);
// 3. 给对象的对应属性赋值
nameField.set(obj, "ligang");
// 4. 读取对应属性的值, 返回object
nameField.get(obj);
可变长度参数
int... args
语法:类型…(必须是三个点)
在方法的形参中只能位于最后,并且只能有一个
可以当作一个数组
反射Method
- getReturnType 获取返回值类型
- getModifiers 获取修饰符列表
- getParameterTypes -> Class[] 获取参数类型
```java
public class UserService{
public booleab login(String name, String password){
} }pass;
// 1. 获取类名 Class studentClass = Class.forName(“com.liangwei.dao.UserService”); // 2. 获取属性(通过名字获取) Field nameField = studentClass.getDeclaredMethods();
<a name="dl4uO"></a>
## 反射调用对象的方法
```java
// 1. 获取类
Class userServiceClass = Class.forName("");
// 2. 新建对象
Object obj = userServiceClass.newInstance();
// 3. 获取Method
Method loginMethod = userServiceClass.getDeclaredMethod("方法名", 形参列表);
Method loginMethod = userServiceClass.getDeclaredMethod("login", String.class, String.class);
Method loginMethod = userServiceClass.getDeclaredMethod("login", int.class);
// 4. 调用方法
Object retValue = loginMethod.invoke(obj, "admin", "123);