【Java学习笔记】67:通过反射获取构造器以创建对象,越过权限检查使用成员

标签: 反射 Reflection
22人阅读 评论(0) 收藏 举报
分类:

获得类的构造器

通过反射获得类的Class对象,然后就要获得其构造器,才能去创建对象。

package testReflect;

import java.lang.reflect.Constructor;

//自定的一个类
class MyClass {
    private int a1;// 私有成员1
    private double a2;// 私有成员2

    // 默认权限的构造器
    MyClass(int b) {
        this.a1 = b;
    }

    // public权限的无参构造器
    public MyClass() {

    }

    // public权限的有参构造器
    public MyClass(double b) {
        this.a2 = b;
    }

    // private权限的有参构造器
    private MyClass(int b1, double b2) {
        this.a1 = b1;
        this.a2 = b2;
    }

}

// 在主类main方法中测试
public class Main {

    public static void main(String[] args) {
        try {
            // 加载类
            Class cls = Class.forName("testReflect.MyClass");
            // 获取所有public权限的构造器
            Constructor[] ary_con1 = cls.getConstructors();
            System.out.println("所有public权限的构造器:");
            for (Constructor c : ary_con1) {
                System.out.println(c);
            }
            // 获取所有的构造器
            Constructor[] ary_con2 = cls.getDeclaredConstructors();
            System.out.println("所有的构造器:");
            for (Constructor c : ary_con2) {
                System.out.println(c);
            }
            // 获取指定的public构造器,传入的是参数表所在的类的Class对象表
            Constructor con3 = cls.getConstructor(double.class);
            System.out.println("指定的public构造器:");
            System.out.println(con3);
            // 获取指定的构造器,传入的是参数表所在的类的Class对象表
            Constructor con4 = cls.getDeclaredConstructor(int.class,
                    double.class);
            System.out.println("指定的构造器:");
            System.out.println(con4);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }
}

输出:

所有public权限的构造器:
public testReflect.MyClass(double)
public testReflect.MyClass()
所有的构造器:
private testReflect.MyClass(int,double)
public testReflect.MyClass(double)
public testReflect.MyClass()
testReflect.MyClass(int)
指定的public构造器:
public testReflect.MyClass(double)
指定的构造器:
private testReflect.MyClass(int,double)

创建类的对象并使用成员

在使用构造器和使用成员时都可以通过.setAccessible(true)解除限定来越过权限检查。

package testReflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//自定的一个类
class MyClass {
    private int a1;// 私有成员1
    private double a2;// 私有成员2

    // private权限的有参构造器
    private MyClass(int b1, double b2) {
        this.a1 = b1;
        this.a2 = b2;
        System.out.println("private构造器被调用了");
    }

    // private权限的成员方法
    private String setNum(int b1, double b2) {
        this.a1 = b1;
        this.a2 = b2;
        System.out.println("private成员方法被调用了");
        return "返回值";
    }

}

// 在主类main方法中测试
public class Main {

    public static void main(String[] args) {
        try {
            // 加载类
            Class cls = Class.forName("testReflect.MyClass");

            // 获取指定的构造器,传入的是参数表所在的类的Class对象表
            Constructor con = cls.getDeclaredConstructor(int.class,
                    double.class);
            // 暴力反射,让这个私有构造器对象可以越过权限检查
            con.setAccessible(true);
            // 使用这个构造器创建对象,传入参数
            Object obj = con.newInstance(2, 3.14);

            // 从Class对象获取指定的成员方法
            Method mthd = cls.getDeclaredMethod("setNum", int.class,
                    double.class);
            // 暴力反射,让这个私有成员方法对象可以越过权限检查
            mthd.setAccessible(true);
            // 调用该成员方法,于刚才创建的对象上,还需传入参数
            Object rslt = mthd.invoke(obj, 9, 6.66);
            System.out.println("返回值是:" + rslt.toString());

            // 从Class对象获取指定的成员
            Field f1 = cls.getDeclaredField("a1");
            Field f2 = cls.getDeclaredField("a2");
            // 暴力反射,让这两个私有成员变量可以越过权限检查
            f1.setAccessible(true);
            f2.setAccessible(true);
            // 为第二个成员变量设置值,于刚才创建的对象上,还需传入值
            f2.set(obj, 8.88);
            // 输出这两个字段的值,于刚才创建的对象上
            System.out.println("a1=" + f1.get(obj) + ",a2=" + f2.get(obj));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
}

输出:

private构造器被调用了
private成员方法被调用了
返回值是:返回值
a1=9,a2=8.88
查看评论

java反射获取构造器以及调用构造器创建对象

Java反射获取构造器   获取某一个类中的所有构造器: 1. 明确操作的是哪一个类(严格的说是类编译后的字节码) 2. 获取构造器 Constructor类:表示类中构造器的类型,Construct...
  • u014207606
  • u014207606
  • 2016-11-27 13:54:00
  • 1655

Java中通过反射越过泛型检查

要想Java通过反射越过泛型检查,你就得先明白,泛型是在什么时候起作用的。 泛型是在编译期间起作用的。在编译后的.class文件中是没有泛型的。所有比如T或者E类型啊,本质都是通过Object处理的。...
  • Marvel__Dead
  • Marvel__Dead
  • 2016-11-21 19:31:40
  • 966

java 反射之越过泛型检查

反射之前,我们知道在集合类中一旦指定了泛型的类型,则只能在该集合中用该类型。但是我们可以利用反射机制来越过泛型检查。比如说利用反射机制获取ArrayList中的add()方法,再调用add方法时,就会...
  • u010930785
  • u010930785
  • 2016-08-05 16:33:35
  • 889

Java通过反射机制使用非默认构造器创建对象

1、Class类方法:getConstructors() 在JDK文档中,对于该方法有如下解释: Returns an array containing Constructor objec...
  • pdcxs007
  • pdcxs007
  • 2014-02-19 10:29:50
  • 3143

通过反射获取私有构造方法并使用

通过反射获取私有构造方法并使用
  • wangyanming123
  • wangyanming123
  • 2016-05-09 18:57:06
  • 2184

通过反射去获取有参构造方法并使用

通过反射去获取有参构造方法并使用
  • wangyanming123
  • wangyanming123
  • 2016-05-09 18:53:57
  • 2027

Java反射机制创建对象

package lxf; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang...
  • smartboy_01
  • smartboy_01
  • 2014-04-08 18:48:46
  • 31327

利用反射越过泛型检查

1.问题描述 现在有一个List list = new ArrayList();如何在list中添加String数据??? 2.问题解决: 利用反射越过泛型检查,我们知道泛型其实就是在编译的时候检查,...
  • w2232097312
  • w2232097312
  • 2016-08-11 14:20:02
  • 240

利用反射调用方法,以及绕过泛型检查

比如知道一个类的对象,我们知道方法的名称,但是只有在运行的时候才知道调用哪个方法,这样只能用反射的方式调用了,拿List举例 List list = new ArrayList(); 但是我们只有...
  • qq_33802316
  • qq_33802316
  • 2017-07-29 11:20:02
  • 250

Java利用反射机制访问私有化构造器

我们都知道,当一个类的构造方法被设为私有的时候(private),在其他类中是无法用new来实例化一个对象的。但是有一种方法可以把带有私有构造器的类实例化出对象。在java的反射机制中,可以通过Cla...
  • ljw_logs
  • ljw_logs
  • 2017-04-13 11:37:57
  • 201
    个人资料
    持之以恒
    等级:
    访问量: 14万+
    积分: 4762
    排名: 7596
    其它
    快毕业了。