博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java 反射
阅读量:6495 次
发布时间:2019-06-24

本文共 2187 字,大约阅读时间需要 7 分钟。

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解析技术。一个例子:
  
  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后边的参数也要传对象。这个有待验证

 

 

转载地址:http://cccyo.baihongyu.com/

你可能感兴趣的文章
Spring Boot 使用parent方式引用时 获取值属性方式默认@
查看>>
Elasticsearch之中文分词器插件es-ik(博主推荐)
查看>>
解决maven下载jar慢的问题(如何更换Maven下载源)
查看>>
linux安装gitLab
查看>>
concurrent包的实现示意图
查看>>
golang os.Args
查看>>
Linux常用命令
查看>>
【重磅】云栖社区2017年度内容特辑
查看>>
Java WEB开发时struts标签 显示set内容
查看>>
spring-data-elasticsearch 概述及入门(二)
查看>>
Solr启动和结束命令
查看>>
1.12 xshell密钥认证
查看>>
3.2 用户组管理
查看>>
awk
查看>>
AliOS Things SMP系统及其在esp32上实现示例
查看>>
VMware虚拟机出现“需要整合虚拟机磁盘”的解决方法
查看>>
ibatis 动态查询
查看>>
汇编语言之实验一
查看>>
git 调用 Beyond Compare
查看>>
SQL基础-->层次化查询(START BY ... CONNECT BY PRIOR)[转]
查看>>