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

    Java允许从配置文件中读取类文件,从类文件(*.class)中反射类的成员变量,成员方法,构造方法,然后直接调用。

    反射一般用来开发框架,比如写好xml配置文件,然后封装好一些反射用的程序就可以做出框架。

    以下是几种常见的反射用法。

    1,反射类的构造方法

    package test;

    import java.lang.reflect.Constructor;

    public class ReflectTest1 {

     public static void main(String[] args) throws Exception {
      Class<?> cls = Class.forName("test.ForTest");//关键就是可以弄字符串这里可以从xml中获取,具体怎么做,可以用一些大公司做的现成的jar包来实现对xml的查询和修改操作,相关技术可以百度 xml解析技术。一个例子:http://blog.csdn.net/zmwg1/article/details/5632022
      
      ForTest tst = (ForTest)cls.newInstance();//这样也可以调用无参构造函数
      tst.showPrivField();
      
      
      Constructor<?> c0 = cls.getConstructor();//获取公有无参构造函数, 括号里面加个null效果一样
      ForTest tst0 = (ForTest)c0.newInstance();//括号里面加个null效果一样
      tst0.showPrivField();
      
      Constructor<?> c = cls.getDeclaredConstructor(String.class);//可获取私有构造函数
      c.setAccessible(true);//使可以访问私有
      ForTest tst1 = (ForTest)c.newInstance("ami");
      tst1.showPrivField();
      
     }

    }

    package test;

    public class ForTest {
     
     private String str = "wowowo";
     
     private static ForTest privField = new ForTest("me");
     
     public ForTest() {}
     
     private ForTest(String str) {
      this();
     }
     
     public void setPrivField(String str1) {
      this.privField.str = str1;
     }
     
     public void showPrivField() {
      System.out.println(privField.privField.privField.privField==privField.privField);
     }
    }

    2,反射类的其他方法

      Class cls = Class.forName("**.**.**");

      Method method = cls.getMethod("方法名",...方法参数类型);//第二个为可变参数,数组类型的用 类似int[].class这种方式

      int[] i = (int[])method.invoke(指定方法所属对象,...方法参数); //直接跑方法 invoke:援引的意思,返回值的类型需要强转再接收。

      获取私有方法要用cls.getDeclaredMethod(……)而非cls.getMethod,并且加上method.setAccessible(true);

      获取的静态方法invoke时是可以传null给对象参数的。

      获取的main方法,invoke的第二个参数位置由于main方法的参数是String[],而invoke第二个参数是可变参数,所以如果传一个String[]给invoke会被解析成多个字符串对象,因此会报main方法参数过多。   

       解决方法一 利用其只解析一次的特点传递new Object[]{new String[]{"",""}},只解析一次就会解析出来一个String[]对象。

       解决方法二 是传一个 (Object)new String[]{""}

      

    3,反射类的字段(成员变量)

      Person p = new Person();

      Class cls = Class.forName("**.**.**");

      Field f = cls.getField("name");

      Object obj = f.get(p);//获取对象p中该字段的值

      Class type = f.getType();//可以获得对象的类型  

      if(type.equals(String.class)){

        String svalue = (String)value;//

      }

      

      f.set(p,"xxxxxxxx");//可以设置字段的值

      Field pw= cls.getDeclaredField("password");//获取私有成员变量

      pw.setAccessible(true);//打开私有的权限

      和静态方法不同,静态成员变量get的时候get后边的参数也要传对象。这个有待验证

  • 相关阅读:
    为什么MySQL数据库索引选择使用B+树?
    nginx负载均衡策略
    视频笔记
    mysql show full processlist 分析问题
    Git利用命令行提交代码步骤
    zend studio远程自动上传代码并执行
    CentOS7 通过YUM安装MySQL5.7 linux
    PHP的按位运算符是什么意思
    git 分支操作
    php 技术知识点汇总
  • 原文地址:https://www.cnblogs.com/flying607/p/3443544.html
Copyright © 2011-2022 走看看