zoukankan      html  css  js  c++  java
  • java反射学习笔记

    1、java反射概念

      JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

      JAVA反射机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

    2、Class类

      Class类用于表示一个.class文件,通过这个类的Class对象可以反射出该类的字段、方法、构造函数、注释等等。任何数据类型都有自己的Class对象。

      获得Class对象的方式有三种:

     1 package reflect;
     2 
     3 public class Dog {
     4     
     5     public static void main(String[] args) throws Exception {
     6         //1、
     7         Class clazz1 = Class.forName("reflect.Dog");
     8         System.out.println(clazz1.getName());
     9         
    10         //2、
    11         Class clazz2 = Dog.class;
    12         System.out.println(clazz2.getName());
    13         
    14         //3、
    15         Class clazz3 = new Dog().getClass();
    16         System.out.println(clazz3.getName());
    17     }
    18     
    19 }

    运行结果:

    reflect.Dog
    reflect.Dog
    reflect.Dog

    3、Constructor类

      Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。Constructor 类的实例对象代表一个类的构造方法。

      3.1、得到某个类所有的构造方法,例:

        Constructor [] constructors= Class.forName("java.lang.String").getConstructors();

      3.2、得到某一个构造方法,例: 

        Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);

      3.3、利用构造方法创建实例对象:
        String str = (String)constructor.newInstance(“abc”);

      3.4、Class类的newInstance()方法也可创建类的实例,其内部工作原理是先得无参的构造方法,再用构造方法创建实例对象。
        String obj =(String)Class.forName("java.lang.String").newInstance();

      

     1 package reflect;
     2 
     3 import java.lang.reflect.Constructor;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 
     7 public class Dog {
     8     private int id;
     9     private String name;
    10     private List list;
    11     
    12     private Dog(List list) {
    13         this.list = list;
    14         System.out.println("反射私有构造函数");
    15     }
    16 
    17     public Dog() {
    18         System.out.println("dog");
    19     }
    20     
    21     public Dog(String name) {
    22         this.name = name;
    23     }
    24     
    25     public Dog(String name, int id) {
    26         this.name = name;
    27         this.id = id;
    28     }
    29     
    30     public int getId() {
    31         return id;
    32     }
    33 
    34     public void setId(int id) {
    35         this.id = id;
    36     }
    37 
    38     public String getName() {
    39         return name;
    40     }
    41 
    42     public void setName(String name) {
    43         this.name = name;
    44     }
    45 
    46     public static void main(String[] args) throws Exception {
    47 
    48         Class clazz = Class.forName("reflect.Dog");
    49         //得到某个类所有的构造方法
    50         Constructor[] Constructors  = clazz.getConstructors();
    51         
    52         //反射无参构造方法
    53         Constructor c1 = clazz.getConstructor(null);
    54         Dog d = (Dog) c1.newInstance(null);
    55         
    56         //反射Dog(String name)构造函数
    57         Constructor c2 = clazz.getConstructor(String.class);
    58         Dog d2 = (Dog) c2.newInstance("guoguo");
    59         System.out.println("d2:"+d2.getName());
    60         
    61         //反射public Dog(String name, int id)构造函数
    62         Constructor c3 = clazz.getConstructor(String.class, int.class);
    63         Dog d3 = (Dog) c3.newInstance("guoguo",12);
    64         System.out.println("d3:"+d3.getId()+"--"+d3.getName());
    65         
    66         //反射private Dog(List list)构造函数
    67         Constructor c4 = clazz.getDeclaredConstructor(List.class);
    68         c4.setAccessible(true);  
    69         Dog d4 = (Dog) c4.newInstance(new ArrayList());
    70         
    71         //或者通过class.newIntance获取对象
    72         Dog d5 = (Dog) clazz.newInstance();
    73     }
    74 }

    运行结果:

    dog
    d2:guoguo
    d3:12--guoguo
    反射私有构造函数
    dog

    3、Field类

       Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。 

      

     1 package reflect;
     2 
     3 import java.lang.reflect.Field;
     4 import java.util.List;
     5 
     6 public class Dog {
     7     private int id;
     8     private String name;
     9     private List list;
    10     
    11     private Dog(List list) {
    12         this.list = list;
    13         System.out.println("反射私有构造函数");
    14     }
    15 
    16     public Dog() {
    17         System.out.println("dog");
    18     }
    19     
    20     public Dog(String name) {
    21         this.name = name;
    22     }
    23     
    24     public Dog(String name, int id) {
    25         this.name = name;
    26         this.id = id;
    27     }
    28     
    29     public int getId() {
    30         return id;
    31     }
    32 
    33     public void setId(int id) {
    34         this.id = id;
    35     }
    36 
    37     public String getName() {
    38         return name;
    39     }
    40 
    41     public void setName(String name) {
    42         this.name = name;
    43     }
    44 
    45     public static void main(String[] args) throws Exception {
    46 
    47         Class clazz = Class.forName("reflect.Dog");
    48         
    49         //获取所有成员变量
    50         Field[] fs = clazz.getDeclaredFields();
    51         for (Field f : fs) {
    52             System.out.println(f.getName());
    53         }
    54         
    55         //private String name; 给变量赋值
    56         Dog d1 = new Dog();
    57         Field f1 = clazz.getDeclaredField("name");
    58         f1.setAccessible(true);
    59         f1.set(d1, "guoguo");
    60         System.out.println();
    61         System.out.println("d1:"+d1.getName());
    62         
    63         //获取变量的值
    64         Dog d2 = new Dog("guoguo");
    65         Field f2 = clazz.getDeclaredField("name");
    66         f2.setAccessible(true);
    67         System.out.println();
    68         System.out.println("d2:"+f2.get(d2));
    69     }
    70 }

    运行结果:

    id
    name
    list
    dog

    d1:guoguo

    d2:guoguo

    4、Method类

       Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反射的方法可能是类方法或实例方法(包括抽象方法)。

      得到类中的某一个方法:

        例子: Method charAt = Class.forName("java.lang.String").getMethod("charAt", int.class);


      调用方法:
        通常方式:System.out.println(str.charAt(1));
        反射方式: System.out.println(charAt.invoke(str, 1));
      如果传递给Method对象的invoke()方法的第一个参数为null,说明该Method对象对应的是一个静态方法!

     1 package reflect;
     2 
     3 import java.lang.reflect.Method;
     4 
     5 public class Dog {
     6 
     7     public void run() {
     8         System.out.println("run1...");
     9     }
    10     
    11     public void run(String str) {
    12         System.out.println("run2....");
    13     }
    14     public void run(String str1, String[] str2, int[] id) {
    15         System.out.println("run3....");
    16     }
    17     
    18     private void say() {
    19         System.out.println("say..");
    20     }
    21     
    22     private String say(String str) {
    23         return str;
    24     }
    25     
    26     public static void eat() {
    27         System.out.println("eat...");
    28     }
    29     
    30     public static void main(String[] args) throws Exception {
    31         Class clazz = Class.forName("reflect.Dog");
    32         Dog d = (Dog) clazz.newInstance();
    33 
    34         //反射public void run()
    35         Method run1 = clazz.getMethod("run",null);
    36         run1.invoke(d,null);
    37         
    38         //反射public void run(String str)
    39         Method run2 = clazz.getMethod("run",String.class);
    40         run2.invoke(d, "str1");
    41         
    42         //反射public void run(String str1,String str2)
    43         Method run3 = clazz.getMethod("run",String.class,String[].class,int[].class);
    44         run3.invoke(d, "str", new String[]{"1","2"},new int[]{1});
    45         
    46         //反射私有方法private void say()
    47         Method say = clazz.getDeclaredMethod("say", null);
    48         say.setAccessible(true);
    49         say.invoke(d, null);
    50         
    51         //反射带返回值的方法private String say(String str)
    52         Method say2 = clazz.getDeclaredMethod("say", String.class);
    53         say2.setAccessible(true);
    54         String result = (String) say2.invoke(d, "aaa...");
    55         System.out.println(result);
    56         
    57         //反射静态方法
    58         Method eat = clazz.getMethod("eat", null);
    59         eat.invoke(null, null);    //null
    60         
    61     }
    62 }

    运行结果:

    run1...
    run2....
    run3....
    say..
    aaa...
    eat...

  • 相关阅读:
    黄聪:解决Web部署 svg/woff/woff2字体 404错误
    黄聪:C#中HtmlAgilityPack判断是否包含或不包含指定的属性或值
    黄聪:GeckoFX如何引用jquery文件并执行自定义JS
    黄聪:css3实现图片划过一束光闪过效果(图片光影掠过效果)
    黄聪:C#带cookie模拟登录百度
    黄聪:如何为IIS增加svg和woff等字体格式的MIME
    黄聪:微信支付错误两个问题的解决:curl出错,错误码:60
    黄聪:《跟黄聪学WordPress插件开发》
    黄聪:GeckoWebBrowser多窗口独立cookie
    黄聪:远程连接mysql数据库注意事项记录(远程连接慢skip-name-resolve)
  • 原文地址:https://www.cnblogs.com/ming-zi/p/5956186.html
Copyright © 2011-2022 走看看