Java 在反射上使用泛型

Java 中 我们可以用类名.Calss or 对象名.getClass()去获得一个Class。
而这个Class本身也是一个类,而且是1个泛型类。

下面是Class源代码的中的定义:

 * @author  unascribed
 * @see     java.lang.ClassLoader#defineClass(byte[], int, int)
 * @since   JDK1.0
 */
public final class Class<T> implements java.io.Serializable,
                              GenericDeclaration,
                              Type,
                              AnnotatedElement {
    private static final int ANNOTATION= 0x00002000;
    private static final int ENUM      = 0x00004000;
    private static final int SYNTHETIC = 0x00001000;

    private static native void registerNatives();
    static {
        registerNatives();
    }
	...

所以在反射中, 我们也可以使用泛型的。
这里只介绍两个常用的泛型类
Class<T>
Constructor<T>

一个例子

我们首先定义个苹果类

@ToString
class Apple{
    private int id;
    private double weight;

    private Apple(int id, double weight){
        this.id = id;
        this.weight = weight;
    }
}

可以见到这个类本身只有1个私有的全参数Constuctor, 所以这个类本身是无法在外部实例化的。
但是我们在其他类仍然可以利用反射构建1个对象


class TestReflect{
    public Apple createObject(int id, double weight) throws NoSuchMethodException, SecurityException, 
                                        InstantiationException, IllegalAccessException, 
                                        IllegalArgumentException, InvocationTargetException{
        Class clz = Apple.class;
        Constructor cstr = clz.getDeclaredConstructor(int.class,double.class);
         //because the constructor defined is private, we need below line to change it to be accessable, 
         //otherwise we will get the Exception below
         //java.lang.IllegalAccessException: Class TestReflect can not access a member of class Apple with modifiers "private"
        cstr.setAccessible(true);
        Object obj = cstr.newInstance(id, weight);
        Apple a = (Apple)obj;
        return a;
    }
}    

这个例子我们没有使用泛型, 用Class 对象去获得 Apple.class 对象。
然后通过 Class 对象clz 去获得被定义的构造函数。 这个构造函数对象也是非泛型对象。

然后我们用setAccessible()方法修改这个私有构造函数可以被外部访问!

接下来newInstance()方法由于没有使用泛型, 所以只会返回1个Object 对象, 我们还需要强制转行成Apple对象。

使用泛型的反射例子

我们创建另1个构造苹果对象的方法:

 public Apple createObjectWithGeneric(int id, double weight) throws NoSuchMethodException, SecurityException, 
                                        InstantiationException, IllegalAccessException, 
                                        IllegalArgumentException, InvocationTargetException{
        Class<Apple> clz = Apple.class;
        Constructor<Apple>  cstr = clz.getDeclaredConstructor(int.class,double.class);
         //because the constructor defined is private, we need below line to change it to be accessable, 
         //otherwise we will get the Exception below
         //java.lang.IllegalAccessException: Class TestReflect can not access a member of class Apple with modifiers "private"
        cstr.setAccessible(true);
        Apple a = cstr.newInstance(id, weight);
        return a;
    }

一旦我们使用Class<Apple> 去接收 Apple.class 的对象
则Contructor<Apple> 这个泛型类就称为 getDeclaredConstructor()的返回类型了。
而其newInstance() 会直接return1个Apple 对象, 无需任何类型转换!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nvd11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值