zoukankan      html  css  js  c++  java
  • java 反射

    类加载方法:

    所有类的对象都是Class的实例。

    类加载时会先加载static静态部分,并且从父类的static到子类static依次加载。

    final语句块会作为宏定义被加载到特殊位置。

    Person类:

     1 public class Person {
     2     private String name;
     3     private int age;
     4 
     5     public Person() {
     6         // TODO Auto-generated constructor stub
     7     }
     8 
     9     public Person(String name, int age) {
    10         this.name = name;
    11         this.age = age;
    12     }
    13 
    14     public String getName() {
    15         return name;
    16     }
    17 
    18     public void setName(String name) {
    19         this.name = name;
    20     }
    21 
    22     public int getAge() {
    23         return age;
    24     }
    25 
    26     public void setAge(int age) {
    27         this.age = age;
    28     }
    29 
    30     public void foo(String s) {
    31         System.out.println("superman is batman's!!" + "   s");
    32     }
    33 
    34     public void foo(String s, int i) {
    35         System.out.println("superman is batman's!!" + "   s" + i);
    36     }
    37 
    38 }

    Demo主函数类:

     1 public class ReflectionDemo {
     2 
     3     public static void main(String[] args) {
     4         // TODO Auto-generated method stub
     5         Person person = new Person();
     6         Class demo1=null;
     7         Class demo2=null;
     8         Class demo3=null;
     9         try {
    10             // 通过包名加载类
    11             demo1 = Class.forName("reflection.Person");
    12         } catch (ClassNotFoundException e) {
    13             // TODO Auto-generated catch block
    14             e.printStackTrace();
    15         }
    16         // 使用类实例反推类
    17         demo2 = person.getClass();
    18         // 使用 “类名.class”加载类
    19         demo3 = Person.class;
    20         System.out.println(demo1.getName());
    21         System.out.println(demo2.getName());
    22         System.out.println(demo3.getName());
    23     }
    24 
    25 }

    输出结果:

    reflection.Person
    reflection.Person
    reflection.Person

    使用Class实例化其他类对象:

    1 public static void main(String[] args) throws Exception {
    2         // 异常未处理
    3         Class c = null;
    4         c = Class.forName("reflection.Person");
    5         Person person = (Person) c.newInstance();
    6         person.setName("naruto");
    7         System.out.println("Person.name :" + person.getName());
    8     }

    输出:

    Person.name :naruto

    这其实是调用Person#Person()默认构造方法,当Person()声明为private私有时,Class.forName()方法会报错。因此在一个类中最好有一个无参构造方法。

    通过构造器操作类的有参函数及无参函数:

     1 public static void main(String[] args) {
     2         Class c = null;
     3         Person p1;
     4         Constructor[] cons; // 声明一个构造器数组
     5         try {
     6             // 加载Person类
     7             c = Class.forName("reflection.Person");
     8             // 通过Class实例化其他对象
     9             p1 = (Person) c.newInstance();
    10             p1.setName("naruto");
    11             System.out.println("p1.name :" + p1.getName());
    12             // 获取全部构造函数
    13             cons = c.getConstructors();
    14             // 构造Person实例,cons数组中的索引值与Person中构造函数声明时的位置有关,如果位置不对应会报错
    15             Person p2 = (Person) cons[1].newInstance("tom", 21);
    16             System.out.println("p2.name :" + p2.getName() + "p2.age :"
    17                     + p2.getAge());
    18         } catch (Exception e) {
    19             e.printStackTrace();
    20         }
    21 
    22     }

    输出:

    p1.name :naruto
    p2.name :tomp2.age :21

    获取类实现的所有接口:

     1 public static void main(String[] args) {
     2         try {
     3             Class<?> c1 = Class.forName("reflection.Person");
     4             Class<?>[] inters = c1.getInterfaces();
     5             for (int i = 0; i < inters.length; i++) {
     6                 System.out.println(inters[i].getName());
     7             }
     8         } catch (Exception e) {
     9             // TODO Auto-generated catch block
    10             e.printStackTrace();
    11         }
    12 
    13     }

    输出:

    reflection.InterfaceDemo

    通过反射获取类信息:

     1 public static void main(String[] args) {
     2         try {
     3             Class<?> class1 = Class.forName("reflection.Person");
     4             // 获取Person类的父类
     5             Class<?> class2 = class1.getSuperclass();
     6             // System.out.println("父类:" + class2.getName());
     7             // 获取全部构造方法
     8             Constructor[] cons = class1.getConstructors();
     9             for (Constructor constructor : cons) {
    10                 System.out.println("构造方法名:" + constructor.getName());
    11                 // 获取构造方法的访问权限
    12                 int no = constructor.getModifiers();
    13                 System.out.println("访问权限:" + Modifier.toString(no));
    14                 // 每个构造方法的参数
    15                 Class p[] = constructor.getParameterTypes();
    16                 for (int i = 0; i < p.length; i++) {
    17                     System.out.print(p[i].getName() + "   ");
    18                 }
    19                 System.out.println();
    20             }
    21             // 获取类全部方法信息
    22             Method[] methods = class1.getMethods();
    23              for (int i = 0; i < methods.length; i++) {
    24              // 获取该方法返回值类型
    25              Class<?> retuTypes = methods[i].getReturnType();
    26              // 获取该方法参数类型
    27              Class<?>[] paraTypes = methods[i].getParameterTypes();
    28              // 获取该方法抛出的异常
    29              Class<?>[] exce = methods[i].getExceptionTypes();
    30              System.out.println();
    31              }
    32             // 获取该类全部非私有的属性信息
    33             Field[] fields = class1.getFields();
    34             // 获取该类全部属性信息,包括私有属性
    35             Field[] fields1 = class1.getDeclaredFields();
    36         } catch (Exception e) {
    37             // TODO Auto-generated catch block
    38             e.printStackTrace();
    39         }
    40 
    41     }

    调用其他类的方法:

     1 public static void main(String[] args) {
     2         try {
     3             Class<?> demo = Class.forName("reflection.Person");
     4             Method method = demo.getMethod("foo",String.class,int.class);
     5             method.invoke(demo.newInstance(),"haha",32);
     6         } catch (Exception e) {
     7             // TODO Auto-generated catch block
     8             e.printStackTrace();
     9         }
    10 
    11     }
    如果方法访问修饰符为private需要修改访问权限
     1 public static void main(String[] args) {
     2         try {
     3             Class<?> demo = Class.forName("reflection.Person");
     4             //getDeclaredMethod()可以访问所有方法,不管方法的访问修饰符是什么
     5             Method method=demo.getDeclaredMethod("fun");
     6             //如果方法访问修饰符为private需要修改访问权限
     7             method.setAccessible(true);
     8             method.invoke(demo.newInstance());
     9         } catch (Exception e) {
    10             // TODO Auto-generated catch block
    11             e.printStackTrace();
    12         }
    13 
    14     }

    访问用private修饰的字段也需要修改访问权限:

     1 public static void main(String[] args) {
     2         try {
     3             Class<?> demo = Class.forName("reflection.Person");
     4             Field field=demo.getDeclaredField("name");
     5             field.setAccessible(true);
     6             Person p=(Person) demo.newInstance();
     7             field.set(p, "pepelu");
     8             System.out.println(field.get(p));
     9         } catch (Exception e) {
    10             // TODO Auto-generated catch block
    11             e.printStackTrace();
    12         }
    13     }
  • 相关阅读:
    Java中存取权限和修饰符public、private、protected和default的区别和联系
    java集合之ArrayList,TreeSet和HashMap分析
    ResultSet,RowSet,OracleCachedRowSet和RowSetMetaData区别及联系
    实战篇
    kubernetes系列之 service代理模式ipvs
    Python Jinja2的简单使用
    Helm v3从入门到实战
    迷宫
    python多线程下载文件
    乱码,编码
  • 原文地址:https://www.cnblogs.com/mada0/p/4721277.html
Copyright © 2011-2022 走看看