首页>>程序代码>>Java反射调用私有方法进行数据传递
Java反射调用私有方法进行数据传递
来源: 时间: 2015-03-03 18:05:43

1 利用反射创建一个无法通过new实例化的类的实例,并调用其私有方法进行数据传递

首先创建一个无法实例化的类:Customer.java:

public class Customer {

    private long id;

    private String name;

    private String age;

    private static Customer instance = null;

    /** 显示将构造函数声明为私有,外界无法通过new来实例化本类 */

    private Customer(){}

    private static synchronized Customer getInstance(){

        if(instance == null){

            return new Customer();

        }

        return instance;

    }

    /** 本set()方法为私有方法,外界无法直接为id属性赋值 */

    private void setId(long id) {

        this.id = id;

    }

    public long getId() {

        return id;

    }

    /** 本set()方法为私有方法,外界无法直接为name属性赋值 */

    private void setName(String name) {

        this.name = name;

    }

    public String getName() {

        return name;

    }

    /** 本set()方法为私有方法,外界无法直接为age属性赋值 */

    private void setAge(String age) {

        this.age = age;

    }

    public String getAge() {

        return age;

    }

}

接下来,开始利用反射创建该类实例,并调用其私有化方法来为其属性赋值,最后调用其公开的方法验证其属性是否被赋上了值:

import java.lang.reflect.Field;

import java.lang.reflect.Method;

public class test {

    public static void main(String[] args) {

   //创建类的实例

     java.lang.Class c = null;

        Customer customer = null;

        try{

            c = Customer.class;

            Method m1 = c.getDeclaredMethod("getInstance");

            m1.setAccessible(true);//这句至关重要,不设置为true,便无法获取私有方法

            customer = (Customer)m1.invoke(c);

        } catch(Exception e){}

        try{

            java.lang.reflect.Field fieldId = customer.getClass().getDeclaredField("id");//获取私有成员变量id

            //获取私有方法setId(int id)

            String firstLetter = fieldId.getName().substring(0, 1).toUpperCase();

            String setName = "set" + firstLetter + fieldId.getName().substring(1);

            String getName = "get" + firstLetter + fieldId.getName().substring(1);

            java.lang.reflect.Method setMethod = customer.getClass().getDeclaredMethod(setName, new Class[]{fieldId.getType()});

            Method getMethod = customer.getClass().getDeclaredMethod(getName, new Class[]{});

            setMethod.setAccessible(true);//使私有方法可以被获取到

            setMethod.invoke(customer, new Object[]{ 23 });//调用该私有方法并传递数据

            System.out.println("-------------通过公共方法获取到的id值:" + customer.getId());

            System.out.println("-------------通过反射获取到的id值:" + getMethod.invoke(customer, null));

            //下面将模仿上面的这一段代码,通过反射来分别为name和age这两个私有成员变量赋值

            Field fieldName = customer.getClass().getDeclaredField("name");

            firstLetter = fieldName.getName().substring(0, 1).toUpperCase();

            setName = "set" + firstLetter + fieldName.getName().substring(1);

            setMethod = customer.getClass().getDeclaredMethod(setName, new Class[]{ fieldName.getType() });

            setMethod.setAccessible(true);

            setMethod.invoke(customer, "张三");

            System.out.println("-----------------姓名:" + customer.getName());

            Field fieldAge = customer.getClass().getDeclaredField("age");

            firstLetter = fieldAge.getName().substring(0, 1).toUpperCase();

            setName = "set" + firstLetter + fieldAge.getName().substring(1);

            setMethod = customer.getClass().getDeclaredMethod(setName, new Class[]{ fieldAge.getType() });

            setMethod.setAccessible(true);

            setMethod.invoke(customer, "40");

            System.out.println("-----------------年龄:" + customer.getAge());

        } catch(Exception e){}

    }

}

这里需要注意:java.lang.reflect.Method貌似是值对象,如果将其传递到另一个方法中并做处理,然后从那个方法中出来后,依然保持其原来的属性不变,没有一点引用类型对象的特征。

  同时,这里的Customer类虽然使用了一个单例模式,但如果我们使用反射的方法来实例化两个该对象实例,它们并非指向同一个引用,例如:

  private static Customer test1(){

        java.lang.Class c = null;

        Customer customer = null;

        try{

            c = Customer.class;

            Method m1 = c.getDeclaredMethod("getInstance");

            m1.setAccessible(true);//这句至关重要,不设置为true,便无法获取私有方法

            customer = (Customer)m1.invoke(c);

        } catch(Exception e){}

  }

  public static void main(String[] args) {

        Customer c1 = test1();

        Customer c2 = test1();

        System.out.println("-----------------------" + c1.equals(c2));

        System.out.println("-----------------------" + (c1 == c2));

    }

  编译后,两个都显示为false。

本页地址:http://www.easytd.com/chengxudaima/d_15030318749.html

网友评论留言

验证码 换一张
上一篇:Java程序实现输入法全角半角之间转换 下一篇:Java jar命令进行java类文件打包