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

    Java反射

     

    1、何为反射? 简而言之: 加载类,并解剖出类的各个组成部分。根据java语言的这一特性,可将Java视为一种动态语言。更好的理解反射机制有助于我们深层次的理解spring框架。

    2、Class类 代表了一个类的字节码。 在 java.lang包中可以找到。

     加载字节码的方法:

     1 Class.forName("全类名"); Class.forName("com.mysql.jdbc.Driver"); 

    该方法的作用是,加载某个类的字节码到内存中,并使用class对象进行封装。

    3、如何获取class对象?下面用Demos.java来举例

     1 package org.reflect.test;
     2 
     3 public class Demos implements Serializable {
     4     
     5     public String demoName0;
     6     public String demoName2;
     7     public String demoName3;
     8     private String demotype0;
     9     private String demotype1;
    10     private String demotype2;
    11     
    12     public Demos(){}
    13     
    14     //构造函数
    15     public Demos(String name, String type) {
    16         
    17     }
    18     
    19     //私有方法
    20     private void getDemoName0(){
    21         
    22         
    23     }
    24     private void setDemoName1(){
    25         
    26         
    27     }
    28     private void setDemoName2(){
    29         
    30         
    31     }
    32     
    33     //共有方法
    34     public void getDemoType0(){
    35         
    36         
    37     }
    38     public void getDemoType1(){
    39         
    40         
    41     }
    42     public void getDemoType2(){
    43         
    44         
    45     }
    46     
    47     //测试方法
    48     public void sayHello(String s){
    49         
    50         System.out.println("Public Hello"+s);
    51     }
    52     
    53     //测试方法
    54     private void sayPrivateHello(String s){
    55         
    56         System.out.println("Private Hello"+s);
    57     }
    58     
    59 }

    获取方式:

    1      //获取class类方式1
    2         Class clazz1=Class.forName("org.reflect.test.Demos");
    3         //方式2
    4         Class clazz2=Demos.class;
    5         //方式3
    6         Class clazz3=new Demos().getClass();

     4、获取包名,全类名,类的修饰符,父类,接口名,构造方法

     1 //获取包名包名
     2         String package1=clazz1.getPackage().getName();
     3         String package2=clazz2.getPackage().getName();
     4         
     5         System.out.println("包名1 :"+package1+"---包名2 :"+package2);
     6         
     7         //获取类全名
     8         String name1=clazz1.getName();
     9         String name2=clazz2.getName();
    10         System.out.println("类名1 :"+name1+"---类名2 :"+name2);
    11         
    12         //获取类的修饰符
    13         int mod=clazz1.getModifiers();
    14         System.out.println("该类的修饰符 :"+Modifier.toString(mod));
    15         
    16         //获取该类的父类
    17         Class supercla=clazz1.getSuperclass();
    18         System.out.println("父类 :"+supercla);
    19         
    20         //获得该类的接口
    21         Class []interfaces=clazz1.getInterfaces();
    22         for (Class i:interfaces) {
    23             System.out.println("接口名  :" + i.getName());
    24         }
    25         
    26         
    27         //获取该类的构造方法
    28         Constructor []con=clazz1.getConstructors();
    29         for (Constructor c :con) {
    30             System.out.println("构造函数名 :"+c.getName());
    31         }
    32         

    输出结果:

     

    5、获取该类的字段的两种方法:

    getFields();
    getDeclaredFields();
     1         //获取该类的字段 ,只限public修饰符修饰的
     2         Field[]fils=clazz1.getFields();
     3         for (Field f :fils) {
     4             System.out.println("fieldsName :"+f.getName());
     5         }
     6         //获取该类的所有的字段,public, protected, default(package) access, and private fields
     7         //不包括继承来的属性
     8         Field []filss=clazz1.getDeclaredFields();
     9         for (Field f :filss) {
    10             System.out.println("DeclaredFields :"+f.getName());
    11         }

     说明:getFields();该方法只获取本类中public修饰的属性,

             getDeclaredFileds();该方法获取该类中所有的属性,包括私有,但是不包括继承来的属性。

    输出结果:

     

    6、获取该类的方法的两种方法:

    getMethods();
    getDeclaredMethods();

     1 //获取该类的特定的方法 public,包括父类的以及接口实现的
     2         Method[]methods=clazz1.getMethods();
     3         for(Method m:methods){
     4             System.out.println("Methods :"+m.getName());
     5         }
     6         
     7         //获取所有的方法,public private 仅限当前类,不包括父类
     8         Method []method3=clazz1.getDeclaredMethods();
     9         for(Method m : method3){
    10             System.out.println("DeclaredMethods :"+m.getName());
    11         }

    说明:getMethods();获取该类public修饰的方法,包括父类及接口实现的

            getDeclaredMethods();只获取本类中的所有方法,包括private修饰的

    输出结果:

     

    7、通过反射调用Demos类中的方法

     1      //获得该类的一个实例
     2         Demos c=(Demos) clazz2.newInstance();
     3         Method  method=clazz2.getMethod("sayHello", String.class);
     4         method.invoke(c, "World!!!");
     5         
     6         //getDeclaredMethod能获取到所有定义的方法。setAccessible方法为true 则可以访问到私有的方法
     7         Demos c2=(Demos) clazz1.newInstance();
     8         Method method2=clazz1.getDeclaredMethod("sayPrivateHello", String.class);
     9         method2.setAccessible(true);
    10         method2.invoke(c2, "World!!!!");

    说明:getMethod("arg0","arg1"); arg0代表方法的名称,arg1代表参数的类型。

       getDeclaredMethod("arg2","arg3"); arg2,arg3的含义同getMethod方法。

    输出结果:

     

    这里有一个小插曲,都知道私有的方法只能供本类使用,属于本类私有,但是这里我们可以看到利用反射可以访问到Demos类中的私有方法,所以下次面试遇到private修饰的方法能被其他类调用吗?就可以说利用反射是可以的 0.0

    我喜欢开发者,程序猿。他们单纯、固执、容易体会到成就感;面对压力,能够挑灯夜战不眠不休;面对困难,能够迎难而上挑战自我。他们也会感到困惑与傍徨,但每个程序员的心中都有一个比尔盖茨或是乔布斯的梦想“用智慧开创属于自己的事业”。我想说的是,其实我是一个猿。
  • 相关阅读:
    修复ecshop商品重量BUG小数位增至五位
    ECSHOP 支付宝发货确认接口,记录支付宝返回的交易号
    php数字补零的两种方法
    PHP获取当前时间的毫秒数(yyyyMMddHHmmssSSS)
    ajax 设置Access-Control-Allow-Origin实现跨域访问
    MySQL Master High Available 源码篇
    MHA 报错:There is no alive slave. We can't do failover
    cdid
    mha error
    mysql relay log参数汇总
  • 原文地址:https://www.cnblogs.com/Garolli/p/5227899.html
Copyright © 2011-2022 走看看