我有一个泛型接口,可以由抽象基类的不同子类实现。
interface PropertyOne<T> {
T type();
List<String> values();
}
在基类中,我定义了一个小的帮助器方法,检查当前实例是否实现了该接口,并在可能的情况下强制转换为该接口:
<T> Optional<T> toProperty(Class<T> clazz){
if (clazz.isAssignableFrom(this.getClass())){
return Optional.of(clazz.cast(this));
}
return Optional.empty();
}
例如,我使用这个helper方法来获取和打印这些值:
void printValues() {
List<String> values = toProperty(PropertyOne.class)
.map(p -> p.values())
.orElse(Collections.emptyList());
System.out.println(values);
}
但这会给我一个不安全的强制转换警告,因为values()
现在返回的是列表
而不是列表
。我知道编译代码后泛型类型信息会丢失,但是由于值
的返回类型总是字符串
类型的列表
,所以它应该是安全的?
if ( this instanceof PropertyOne<?>){
List<String> vs = ((PropertyOne<?>)this).values();
System.out.println(vs);
}
列表
类型信息首先丢失?propertyone
?因为类
上的泛型非常有限,不能以这种方式使用(我想说J.L.class
上的泛型被破坏了,但这可能有点苛刻。它们也有一些用途,只是..不多)。泛型可以表示类实例不能表示的东西;类实例(java.lang.class
的实例可以表示泛型不能表示的东西。具体来说,list
不能表示为类实例,而int.class
是不能用泛型表示的类实例。
换句话说,当您试图在java.lang.class
实例中通信完整的泛型类型(例如propertyone
)时,您就失败了--j.l.class
中的T只能是一个没有泛型的类型。
所以,这不是怎么做的。
必须使用toProperty
方法。不是为了这篇文章中的问题;它是关于尝试在从(可选包装的)toProperty调用派生的PropertyOne实例上调用type()
。
除此之外,您在values()
调用中遇到麻烦的原因似乎没有实际的相关泛型部分,这是因为过时的java规则:一旦您使用“原始”,所有的东西都是原始的,甚至不需要它的东西也是如此。
因此,在toproperty(cropertyone.class)
中,最终将返回一个可选
-一个原始类型,因为这不合适;您需要例如propertyone
,这与propertyone
不同(最后一个是raw的;前者不是)-但是对于class
,您不能这样做,因为class
是断开的。现在您进入了原始领域,在这个原始类型上调用values()
最终将返回一个原始列表(只是list
),您可能认为这仍然会给您一个list
,因为values()
的返回类型不依赖于propertyone
的泛型,但这不是它的工作方式,java lang规范说不是。
有几种方法可以解决这个难题,但大多数情况下你只是在这里滥用泛型,你真的做不到这些。请记住,泛型是编译器想象中的虚构:它们在运行时根本不存在。无法运行时检查任何内容。一旦开始混合泛型和运行时构造,如instanceof
或x.isassignablefrom
,就永远不会成功。
如果必须的话,您可以使用一种叫做“超级类型标记”的东西--您可以在谷歌上搜索它(在'java'中加入关键字),这些标记可以非常精确地表示泛型中的任何内容。但这听起来仍然是个错误;但我不能告诉你们在这里要做什么,你们的问题描述是在谈论一个破碎的解决方案,而不是破碎的解决方案试图解决的问题。
我有一个父类来处理我所有的自定义异常,父母异常。我希望所有的子异常都有一个方法来向异常添加消息。为了做到这一点,我创建了一个泛型方法,在向其添加消息后返回泛型类型的对象。我在父类方法中使用来添加消息,然后返回,但是由于该方法返回泛型类型,所以我将其转换为泛型类型T。这似乎是可行的,但是给出了警告。我的代码如下: 该行给出的警告是。这种方法似乎确实如预期的那样有效,所以我并不担心,但我想更好地理解为
问题内容: 我不明白为什么在尝试执行以下操作时会收到警告(未经检查的演员表): 我的意思是将castedMap发布到外部代码的危险是什么?两种操作均可在运行时完美运行: 使用SomeType类型的键从castedMap获取元素 使用SomeType类型的键将元素放入castedMap中。 我只是使用@SuppressWarnings(“ unchecked”)取消警告。 问题答案: 答案可能很无聊
问题内容: 我遇到了Java的异常行为,似乎是一个错误。是吗?即使对象不是的实例,也无法将对象强制转换为通用类型(例如)。这是一个例子: 更新 :感谢cletus和Andrzej Doyle的有用答案。因为我只能接受一个,我接受安杰伊·多伊尔的答案,因为它使我一个解决方案,我觉得是不是 太 糟糕。我认为这是在单行代码中初始化小型Map的更好方法。 然后您这样称呼它: 问题答案: 就像cletus所
我正在编写一个泛型方法,它处理泛型接口的请求类型,并返回一个泛型响应。 前面提到的是我的接口、方法和Pojos。 现在,我正在编写一个请求处理程序,其中有一个方法 上述代码的问题是,在调用私有方法 buildResponse 时,我必须强制转换我的响应,但我只是想知道在定义 T 时,我已经指定了 T 扩展响应,而我的私有方法返回实现响应的 MyResponse,那么为什么需要强制转换呢?
我在这里遇到了一个关于带列表的泛型有界类型的小问题。请帮帮我! 有什么方法可以克服这个问题,或者我可以安全地压制警告吗?
有没有一种简单的方法可以做到这一点: 编辑:我写了一份正确答案的工作副本: