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所做的一个例子,通过强制转换它,我可以访问其他方法来获得它。