- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我对下面的代码有以下疑问:
public class GenericBridgeMethods <T> {
public static void main(String[] args) {
List obj = new ArrayList<Integer>();
List <?> l1 = (List<?>) obj; // clause 1
GenericBridgeMethods <?> g1 = (GenericBridgeMethods<?>) obj; // clause 2
}
}
一个。第 1 条当然不会给出 unchecked cast warning
b.第2条也没有给出unchecked cast warning
我注意到从原始类型 (obj) 到任何可具体化类型(如 GenericBridgeMethods 或 GenericBridgeMethods )的转换不会给出未经检查的转换警告。如果运行此代码,将在第 2 条出现运行时错误。
编译器是否应该在第 2 条给出警告
编辑 1:
ArrayList a1 = new ArrayList<Integer>(); // clause 3
Number n1 = (Number)a1; // clause 4 ERROR
Comparable c1 = (Comparable)a1; // clause 5
List l1 = new ArrayList<Integer>(); // clause 6
Number n2 = (Number)l1; // clause 7
Comparable c2 = (Comparable)l1; // clause 8
谁能解释一下为什么只有第4条有错误?
最佳答案
好吧,首先在 GenericBridgeMethods
中定义了它,T
不是可具体化的类型。 Reifiable 意味着该类型将被编码到类中并在运行时可用。 T
不是这样。
第 2 条不会给出运行时警告,因为它已被检查:将进行运行时检查以确保 obj
类型可分配给 GenericBridgeMethods
类型。由于您已选择通配符作为类型参数,因此无需检查有关 T
的任何内容。
如果另一方面你做了这样的事情:
GenericBridgeMethods<String> g1 = (GenericBridgeMethods<String>) obj;
会给你一个未经检查的赋值警告,因为 obj
是 String
的 GenericBridgeMethods
无法在运行时检查。但是,如果您这样做,则会出现相同的警告:
List<String l1 = (List<String>) obj;
如果您对为什么编译器允许您尝试将 List
转换为 GenericBridgeMethods
感到困惑,答案是因为编译器无法知道GenericBridgeMethods
及其子类的整个层次结构。可能有一个 GenericBridgeMethods
的子类实现了 List
,在这种情况下,转换可能是合法的。
但是,如果您将 GenericBridgeMethods
设为最终类(并因此阻止它拥有子类),您将得到一个编译错误。在这种情况下,您将收到不可转换的类型错误。
只是为了向您展示您的问题与可具体化的类型和泛型无关,请看一下:
public static void main(String[] args) {
List obj = new ArrayList<Integer>();
//this is allowed (no warning), even though it will fail at runtime
CharSequence sequence = (CharSequence) obj;
}
您可以显式地将 obj
转换为 CharSequence
,即使您知道它会在运行时失败。原因是因为编译器只知道 obj
是 List
的一种。由于 List
是一个接口(interface),因此 CharSequence
的实现可能也是一个 List
,因此必须允许转换。
每个 显式转换都有一定程度的在运行时失败的可能性。否则,这将是一个冗余转换,编译器应该允许您省略显式转换。
ArrayList a1 = new ArrayList<Integer>(); // clause 3
Number n1 = (Number)a1; // clause 4 ERROR
Comparable c1 = (Comparable)a1; // clause 5
List l1 = new ArrayList<Integer>(); // clause 6
Number n2 = (Number)l1; // clause 7
Comparable c2 = (Comparable)l1; // clause 8
您想知道为什么只有“第 4 条”不能编译。我想我已经在上面和评论中对此进行了解释,但我将逐步为您完成这个具体示例。
ArrayList a1 = new ArrayList<Integer>(); // clause 3
Number n1 = (Number)a1; // clause 4 ERROR
将 a1
转换为 Number
不起作用,因为 Number
和 ArrayList
都是类,而不是接口(interface)。因为 Java 不允许从多个类 继承,对于一个对象同时是Number
和ArrayList
的实例,Number
必须是 ArrayList
的子类,反之亦然。这在编译时是不正确的。
ArrayList a1 = new ArrayList<Integer>(); // clause 3
Comparable c1 = (Comparable)a1; // clause 5
由于 Comparable
是一个接口(interface),ArrayList
的子类可能是一个 Comparable
。
List l1 = new ArrayList<Integer>(); // clause 6
Number n2 = (Number)l1; // clause 7
由于 List
是一个接口(interface),Number
的子类可以实现 List
。编译器在检查 l1
包含 ArrayList
的转换时并不知道。
关于Java 泛型 : Casting a raw type to any reifiable type doesn't generate unchecked cast warning,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7676981/
我很确定我不会是第一个被这个绊倒的人,但我找不到答案。这是作业。 class Tier{} class Fisch extends Tier{} class Vogel extends Tier{}
在接收器开发人员指南中如下: Applications running on the Google Cast receiver device (receiver applications) are a
最近我制作了一个自定义本地 Flask 网站,用于从本地设备转换到连接到我的电视的 RPi4。有一个 GUI它也可以通过 GET 请求控制,这是转换工作的主要方式,实际上是通过 GET 请求将数据从
最近我因为某些原因重置了我的路由器,所以当我尝试将它连接到 chromecast 时,Chromecast 没有在其列表中列出我的 wifi 名称。 之前它工作正常,所以我选择其他并手动输入我的网络名
做这样的 Actor 阵容的好方法是什么? seq { yield (box "key", box "val") } |> Seq.cast 因为这看起来非常难看: seq { yield (box
我继承的遗留 Web 应用程序是在经典 ASP 中为新西兰乐施会定制编写的,它在用户提交的输入上运行字符串替换,删除字符串“cast”,大概是因为 cast 函数。 然而,这意味着我们的参与者都不能拥
我去了三星网站并下载了 Media Control SDK 包。当我在我的 Galaxy S3 Android 4.3 上使用 AllShare Cast 视频播放器时,我的智能电视(在同一网络中)出
如何在 BigQuery 中查看 INT64 的二进制表示形式?将其转换为 BYTES 类型也可以。 最佳答案 正如@Elliot Brossard 所述,INT64 如何执行是一个实现问题。类型表示
Google 的文档要求我们设置自己的网络服务器来托管 receiver.html。 是否有任何人都可以使用的默认公共(public) chrome-cast 接收器? 我只需要非常基本的接收器,与
我在 Eclipse 3.6 (Helios) 中运行某人的代码时遇到问题。代码是用 OpenJDK 7 编写的。我运行的是 Windows 7,我必须为它安装 Java 7。我之前使用的是 Java
所以我有一些 COM 类型,它们的名称很难记住、又长又笨重,所以如果可以避免的话,我宁愿在从对象进行转换时不必键入它们。使用 Seq.cast 它将推断所需的类型并根据需要进行强制转换。 这是一个用
假设您不关心编译器和机器的转换风格,以下之间是否存在明显差异: #include #include #include static int64_t tosigned (void *p) {
我的测试类 XString 有两个转换运算符。但是编译器不会为 fooA 使用显式转换 operator const wchar_t*()。为什么? class XString { public:
我有以下代码: T imageCollectionItem; // This checks if image actually exists, if it doesn't it gets the ne
这有点假设,因为我不太担心性能 - 只是想知道一般来说哪个选项实际上最快/最有效,或者是否没有任何区别。 假设我有以下支持重载的访问者模板代码: #define IMPLEMENT_VISITOR_W
我目前正在存储复选框的真/假状态。在注册表中检查值以在下次加载表单时重置。 加载表单时,我获取值并像这样设置复选框。 string value = (string)Registry.GetValue(
enum Gender { Male, Female } var k = new[] { Gender.Male }.Cast().ToList().Cast().ToList(); //alrigh
我正在按照 https://codelabs.developers.google.com/codelabs/cast-receiver#0 上的教程构建一个 chrome cast 自定义接收器。我无
我看不懂以下作品 SELECT price, CAST(price AS DECIMAL(10,2)) FROM orders; 但是更新失败: UPDATE orders SET price = C
在 Cast v3 中,如何手动更改“停止转换”按钮的颜色? 我可以为其他所有内容更改转换对话框或媒体路由器的样式,但“停止转换”按钮似乎会根据背景颜色切换为黑色/蓝色。 我的主题:
我是一名优秀的程序员,十分优秀!