class类

什么是反射?

反射就是Reflection,Java的反射是指程序在运行期可以拿到一个对象的所有信息。

方法一:直接通过一个class的静态变量class获取:

  1. Class cls = String.class;

方法二:如果我们有一个实例变量,可以通过该实例变量提供的getClass()方法获取:

  1. String s = "Hello";
  2. Class cls = s.getClass();

方法三:如果知道一个class的完整类名,可以通过静态方法Class.forName()获取:

  1. Class cls = Class.forName("java.lang.String");

访问字段

Class类提供了以下几个方法来获取字段:

  • Field getField(name):根据字段名获取某个public的field(包括父类)
  • Field getDeclaredField(name):根据字段名获取当前类的某个field(不包括父类)
  • Field[] getFields():获取所有public的field(包括父类)
  • Field[] getDeclaredFields():获取当前类的所有field(不包括父类)
  1. import java.lang.reflect.Field;
  2. public class ErrorDemo{
  3. public static void main(String[] args) throws Exception{
  4. // 获取字段值
  5. //Object p = new Person("xiaoshuai");
  6. //Class c = p.getClass();
  7. //Field f = c.getDeclaredField("name");
  8. //
  9. //f.setAccessible(true); // 允许访问隐藏字段
  10. //Object value = f.get(p);
  11. //System.out.println(value);
  12. // 设置字段值
  13. Person p = new Person("xiaoshuai");
  14. System.out.println(p.getName());
  15. Class c = p.getClass();
  16. Field f = c.getDeclaredField("name");
  17. f.setAccessible(true);
  18. f.set(p,"shao shuai");
  19. System.out.println(p.getName());
  20. }
  21. }
  22. class Person{
  23. //public String name;
  24. private String name;
  25. public Person(String name){
  26. this.name = name;
  27. }
  28. public String getName(){
  29. return this.name;
  30. }
  31. }
  32. // 通过反射读写字段是一种非常规方法,它会破坏对象的封装。

调用方法

  1. public class ErrorDemo{
  2. public static void main(String[] args) throws Exception{
  3. Class stdClass = Student.class;
  4. // 获取public方法getScore,参数为String:
  5. System.out.println(stdClass.getMethod("getScore", String.class));
  6. // 获取继承的public方法getName,无参数:
  7. System.out.println(stdClass.getMethod("getName"));
  8. // 获取private方法getGrade,参数为int:
  9. System.out.println(stdClass.getDeclaredMethod("getGrade", int.class));
  10. }
  11. }
  12. class Person{
  13. public String getName(){
  14. return "Person";
  15. }
  16. }
  17. class Student extends Person{
  18. public int getScore(String type){
  19. return 99;
  20. }
  21. private int getGrade(int year){
  22. return 1;
  23. }
  24. }

调用方法

  1. /*
  2. Constructor对象封装了构造方法的所有信息;
  3. 通过Class实例的方法可以获取Constructor实例:getConstructor(),getConstructors(),getDeclaredConstructor(),getDeclaredConstructors();
  4. 通过Constructor实例可以创建一个实例对象:newInstance(Object... parameters); 通过设置setAccessible(true)来访问非public构造方法。
  5. */

获取继承关系

  1. Class i = String.class; // 获取到String的Class
  2. Class s = i.getSuperclass(); // 获取到i对象的父类
  3. // 通过Class对象可以获取继承关系:
  4. // Class getSuperclass():获取父类类型;
  5. // Class[] getInterfaces():获取当前类实现的所有接口。
  6. // 通过Class对象的isAssignableFrom()方法可以判断一个向上转型是否可以实现。

动态代理

  1. Java标准库提供了动态代理功能,允许在运行期动态创建一个接口的实例;
  2. 动态代理是通过Proxy创建代理对象,然后将接口方法“代理”给InvocationHandler完成的。