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后边的参数也要传对象。这个有待验证

 

 

posted @ 2013-11-26 16:16  剑握在手  阅读(175)  评论(0编辑  收藏  举报
返回顶部↑