java反射的学习

来源:互联网 发布:染色体分析软件 编辑:程序博客网 时间:2024/06/07 05:44

今天学习java反射机制:

常见方法

关于反射,常用的有如下一些方法:

clazz.getDeclaredField(name);//获取指定的私有属性clazz.getField(name);//获取指定的公有属性clazz.getSimpleName();//获得类名clazz.getConstructor(parameterTypes);//获取构造函数clazz.getClassLoader();//获取类加载器clazz.getComponentType();clazz.getConstructors();//获取所有的共有的构造方法clazz.getDeclaredConstructor(parameterTypes);//获取私有的指定参数的构造方法clazz.getDeclaredFields();//获取所有的属性clazz.getMethod(name, parameterTypes);//获取指定方法名的方法clazz.getDeclaredMethods();//获取所有的方法clazz.getDeclaredMethod(name, parameterTypes);//获取指定方法名的私有方法

运行私有方法

首先新建一个用于反射操作的类People

People.java

public class People {private void say() {System.out.println("=====saysay=======");}}
利用反射来运行该方法:

Class clazz = Class.forName("com.test.refelect.People");//Class clazz = new People().getClass();//Class clazz = People.class;People people = (People) clazz.newInstance();Method method = clazz.getDeclaredMethod("say",null);//得到私有的方法//需要设置accessible为true否则会抛出//can not access a member of class com.test.refelect.People with modifiers "private"method.setAccessible(true);method.invoke(people, null);//这句代码表示运行people对象的method方法


使用反射操作类属性

进一步,我们给People.java文件中添加如下属性和方法

private String testChangeString = "aaabbbccaaddaa";private String fruit;private String name;private int age;private String[]address = new String[3];public String getFruit() {return fruit;}public void setFruit(String fruit) {this.fruit = fruit;}public People(String name, int age, String[] address) {this.name = name;this.age = age;this.address = address;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String[] getAddress() {return address;}public void setAddress(String[] address) {this.address = address;}public People() {}

利用反射运行setName方法:

Method method = clazz.getMethod("setName",String.class)//由于setName是公有的方法,所以这里调用getMethod方法method.invoke(people,(Object)(new String("小明")));System.out.println(people.getName());
利用反射运行构造函数来new一个实例对象:

Constructor constructor = clazz.getConstructor(String.class,int.class,String[].class);//这里需要传入参数的类型//这里需要将所有的参数转换成Object类型People people2 = (People) constructor.newInstance(new Object[]{"xiaoming",22,new String[]{"china","shanxi","xi'an"}});System.out.println(people2.getName()+people2.getAge()+people2.getAddress()[0]+people2.getAddress()[1]+people2.getAddress()[2]);

利用反射将testChangeString属性中的所有a改为b

Field field = clazz.getDeclaredField("testChangeString");field.setAccessible(true);field.set(people,field.get(people).toString().replace('a','b'));System.out.println(field.get(people).toString());

利用反射更改属性的值:

Field fruitField = clazz.getDeclaredField("fruit");fruitField.setAccessible(true);fruitField.set(people,"apple");System.out.println(fruitField.get(people));method = clazz.getMethod("setFruit",String.class);method.invoke(people,"banbanba");System.out.println(clazz.getMethod("getFruit",null).invoke(people, null));

反射和可变参数

反射和可变参数结合使用,首先在People.java文件中添加如下方法:

private  List<String> getStrings(String a,String b,String ... c) {List<String>returnStr = new ArrayList<String>();returnStr.add(a);returnStr.add(b);for (int i = 0; i < c.length; i++) {returnStr.add(c[i]);}return returnStr;}

利用反射运行发方法如下:

Class clazz = Class.forName("com.test.refelect.People");People people = (People) clazz.newInstance();@SuppressWarnings("unchecked")Method method = clazz.getDeclaredMethod("getStrings",String.class,String.class,String[].class);method.setAccessible(true);@SuppressWarnings("unchecked")List<String>list = (List<String>) method.invoke(people,new Object[]{"aaaa","bbbb",new String[]{"cccc","dddd","eee","fff"}});//System.out.println(list.size());for (String string : list) {System.out.println(string);}

内部类使用反射

下面我创建一个测试类,来演示如何正常或者通过反射实例化内部类,并且运行其中的方法。
People.java
package com.reflect.study;public class People {public void sayHello() {System.out.println("hello world");}class InnerOne {public void walk() {System.out.println("i am walk");}}// 公有内部类public static class InnerTwo {public void run() {System.out.println("i am running");}}// 私有内部类private class InnerThree {private String name;public InnerThree(String name) {super();this.name = name;}private void stop(String address) {System.out.println(name+"is stoping at "+address);}}}

创建内部类实例

    这里需要注意的是<font color='red'> 获取内部类构造方法时,需要将其外部类的类对象作为参数传进去,同样实例化内部类时,也需要将外部类对象作为参数传进</ftont>
// 实例化非静态内部类InnerOne innerOne = new People().new InnerOne();innerOne.walk();// 实例化公有静态内部类People.InnerTwo innerTwo = new People.InnerTwo();innerTwo.run();===================================================================================================

使用反射方式实例化内部类,并调用其方法
try {Class innerOne = Class.forName("com.reflect.study.People$InnerOne");Constructor innerOneConstructor = innerOne.getDeclaredConstructor(People.class);System.out.println(innerOneConstructor);Method walkMethod = innerOne.getDeclaredMethod("walk",null);walkMethod.invoke(innerOneConstructor.newInstance(new People()),null);// public static内部类    Class innerTwo = Class.forName("com.reflect.study.People$InnerTwo");Method runMethod = innerTwo.getDeclaredMethod("run",null);runMethod.invoke(innerTwo.newInstance(), null);Class innerThree = Class.forName("com.reflect.study.People$InnerThree");    Constructor innerThreeConstructor = innerThree.getDeclaredConstructor(new Class[]{People.class,String.class});    Method stopMethod = innerThree.getDeclaredMethod("stop",String.class);    stopMethod.setAccessible(true);    stopMethod.invoke(innerThreeConstructor.newInstance(new Object[]{new People(),"小明"}),"大马路");} catch (Exception e) {e.printStackTrace();}




源码下载


0 0