使用反射机制实例化对象

java代码写一遍,在不改变java源码的情况下,可以创建不同的类

使用newInstance方法

  1. Class c = Class.forName("java.lang.String");
  2. Object obj = c.newInstance(); // java9 以后过时
  • newInstance()会调用无参数构造方法,所以类里面最好保持无参构造方法

获取类路径下的绝对路径

FileReader reader = new FileReader("chapter25/classinfo.properties");
该方法的缺点:移植性差.在IDEA中默认的当前路径是project的根
如果离开IDEA,换到其他位置,可能当前路径就不是project的根了.

注意:使用该方法的前提,是,该文件必须在类路径下. 类路径: src文件夹

  1. // Thread.currentThread() 当前线程对象
  2. // getContextClassLoader() 线程对象的方法,获取当前线程的类加载器
  3. // getResource("classinfo.properties") 【获取资源】这是类加载器的方法,默认从类的根路径下加载资源
  4. String path = Thread.currentThread().getContextClassLoader().getResource("classinfo.properties").getPath();

直接以流的形式返回

  1. InputStream reader = Thread.currentThread().getContextClassLoader()
  2. .getResourceAsStream("路径");
  3. Properties pro = new Properties();
  4. pro.load(reader);
  5. reader.close();
  6. // 通过key获取value
  7. String className = pro.getProperty("className");

java.util包下的资源绑定器

使用这个方法的时候,属性配置文件必须放到类路径下
限制:

  • 文件必须直接放在类路径下(src目录下)
  • 只能是properties文件
  • 路径的时候只要文件名
    1. ResourceBundle bundle = ResourceBundle.getBundle("db");
    2. 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();

}

  1. <a name="roRrB"></a>
  2. ## 通过反射机制获取java对象的属性 **
  3. 使用`getDeclaredField` 只能访问public方法<br />使用setAccessible(True) 打破封装
  4. ```java
  5. // 1. 获取类名
  6. Class studentClass = Class.forName("com.liangwei.bean.Student");
  7. // 2. 获取属性(通过名字获取)
  8. Field nameField = studentClass.getDeclaredField("name");
  9. // 私有属性,使用该语句可以打破封装
  10. nameField.setAccessible(True);
  11. // 3. 给对象的对应属性赋值
  12. nameField.set(obj, "ligang");
  13. // 4. 读取对应属性的值, 返回object
  14. 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);