Java 类型安全代理创建

Java 类型安全代理创建,java,generics,reflection,Java,Generics,Reflection,假设我有两种方法: private <T> T testGenericsT(Class<T> clazz) { Class[] classArray = {clazz}; return (T) newProxyInstance( clazz.getClassLoader(), classArray, (proxy, method, args) -> null ); } private T

假设我有两种方法:

private <T> T testGenericsT(Class<T> clazz) {
    Class[] classArray = {clazz};
    return (T) newProxyInstance(
        clazz.getClassLoader(),
        classArray,
        (proxy, method, args) -> null
    );
  }
private T testGenericsT(类clazz){
类[]类数组={clazz};
返回(T)newProxyInstance(
clazz.getClassLoader(),
类数组,
(代理、方法、参数)->null
);
}
以及:

private-AccessibleStreamable测试泛型(clazz类){
类[]类数组={clazz};
返回(AccessibleStreamable)newProxyInstance(
clazz.getClassLoader(),
类数组,
(代理、方法、参数)->null
);
}
上面的那个不是类型安全的,我得到警告了

未选中将java.lang.Object强制转换为T

但较低的一个是可以接受的,从我的观点来看,我不确定这些不同之处。有什么办法可以让上面的那个安全吗

我在这里遗漏了什么,为什么将它转换为一个可访问的可共享但不是T是完全好的呢

我甚至可以像这样更改代码

  private AccessibleStreamable testGenerics(Class<AccessibleStreamable> clazz) {
    Class[] classArray = { List.class };
    return (AccessibleStreamable) newProxyInstance(
        Map.class.getClassLoader(),
        classArray,
        (proxy, method, args) -> null
    );
  }
private-AccessibleStreamable测试泛型(clazz类){
类[]类数组={List.Class};
返回(AccessibleStreamable)newProxyInstance(
Map.class.getClassLoader(),
类数组,
(代理、方法、参数)->null
);
}
它仍然不会发出任何警告。当然,我不希望它给我一个警告,说我正在做一个未经检查的t型演员

但我想我的主要问题是,有没有办法让上面的安全?(我并不是说要取消警告)

非常简单:

从我的观点来看,我不确定这些不同之处

第一个示例使用了一个泛型类型参数T。该参数可以是任何

第二个示例使用一个显式类名(AccessibleStreamable)

当然,因为,那种类型的T。。。在运行时不存在。第二种方法有一个固定的类型,强制转换没有问题。

非常简单:

从我的观点来看,我不确定这些不同之处

第一个示例使用了一个泛型类型参数T。该参数可以是任何

第二个示例使用一个显式类名(AccessibleStreamable)

当然,因为,那种类型的T。。。在运行时不存在。而第二种方法有一个固定的类型,即强制转换没有问题。

(T)
的强制转换不一定是不安全的(尽管它仍然是强制转换)。警告只意味着在该点没有实际的强制转换,因为没有对
T
的实际类的内置引用

我看到您还将
传递给该方法。您可以使用它在该点手动执行选中的强制转换,类似于您的第二个代码段:

private <T> T testGenericsT(Class<T> clazz) {
    Class<?>[] classArray = {clazz};
    return clazz.cast(newProxyInstance(
        clazz.getClassLoader(),
        classArray,
        (proxy, method, args) -> null
    ));
}
private T testGenericsT(类clazz){
类[]类数组={clazz};
返回clazz.cast(newProxyInstance(
clazz.getClassLoader(),
类数组,
(代理、方法、参数)->null
));
}
(T)
的强制转换并不一定是不安全的(尽管它仍然是强制转换)。警告只意味着在该点没有实际的强制转换,因为没有对
T
的实际类的内置引用

我看到您还将
传递给该方法。您可以使用它在该点手动执行选中的强制转换,类似于您的第二个代码段:

private <T> T testGenericsT(Class<T> clazz) {
    Class<?>[] classArray = {clazz};
    return clazz.cast(newProxyInstance(
        clazz.getClassLoader(),
        classArray,
        (proxy, method, args) -> null
    ));
}
private T testGenericsT(类clazz){
类[]类数组={clazz};
返回clazz.cast(newProxyInstance(
clazz.getClassLoader(),
类数组,
(代理、方法、参数)->null
));
}

不,没有办法,因为类型擦除。警告是这样说的:如果对象不是T的实例,则无法使强制转换失败,因为T在运行时被擦除。不,没有办法,因为类型擦除。这就是警告所说的:如果对象不是T的实例,则无法使强制转换失败,因为T在运行时被擦除。该类是我从Spring获得的,因此它不在我的控制范围内,但感谢您的回答。我以前使用过类似ParameterizedType的方法来查找可选的和类似的内容中的值,并在考虑我是否可以在这里执行类似的操作。@nesohc但是ParameterizedType会为实际参数返回一个
Type[]
。一个
也是一个
类型
,所以你已经在那里了。我真的不明白你说的是什么意思?这是一个很坏的例子,我的意思是如果我能以某种方式访问它。我想把它作为我对ParameterizedType所做的一个例子,通过强制转换,我可以访问其他方法来获得它。这个类是我从Spring获得的,所以它不在我的控制范围之内,但是谢谢你的回答。我以前使用过类似ParameterizedType的方法来查找可选的和类似的内容中的值,并在考虑我是否可以在这里执行类似的操作。@nesohc但是ParameterizedType会为实际参数返回一个
Type[]
。一个
也是一个
类型
,所以你已经在那里了。我真的不明白你说的是什么意思?这是一个很坏的例子,我的意思是如果我能以某种方式访问它。我想把它作为我对ParameterizeType所做的一个例子,通过强制转换它,我可以访问其他方法来获得它。