更准确地说,假设B
是一个类或接口,a
是B
的超类或超接口,B
中的方法声明M2
重写或隐藏a
中的方法声明M1
。然后:
>
如果M2
有一个throws子句提到任何检查的异常类型,那么M1
必须有一个throws子句,否则将发生编译时错误。
对于M2
的throws子句中列出的每个检查异常类型,相同的异常类或其一个超类型必须出现在M1
的throws子句的擦除(§4.6)中;否则,将发生编译时错误。
如果m1
的未擦除的throws子句不包含M2
的throws子句中的每个异常类型的超类型(如果需要,可以修改为m1的类型参数),则会出现编译时未检查的警告,除非@suppresswarnings
禁止
有人能解释一下这是什么意思吗?M1
的未擦除的throws子句?
考虑以下示例
class Base1 extends Exception {}
class Base2 extends Exception {}
class Child1 extends Base1 {}
class Child2 extends Base2 {}
class Child3 extends Base2 {}
class A {
// m1
protected <T extends Base2> void method() throws T {
}
}
class B extends A {
// m2
protected void method() throws Child2 {
}
}
使用javac
编译此代码会产生以下警告:
warning: [unchecked] method() in B cannot override <T>method() in A
protected void method() throws Child2 {
^
overridden method does not throw Child2
where T is a type-variable:
T extends Base2 declared in method <T>method()
因为观察基方法,child3
也可能被抛出,但是观察重写方法,只能抛出child1
。
如果使用无界类型参数,Java Compiler将使用Object替换泛型类型参数,如果绑定参数用作方法参数,则使用类型替换。 例子 (Example) package com.wenjiangs; public class GenericsTester { public static void main(String[] args) { Box<Integer> integer
问题内容: 类型擦除应该擦除所有泛型信息…如果是这种情况,那么像GSON这样的库如何使用泛型来确定反序列化为哪种类型? 例如 这将反序列 化为 将反序列化为 因此以某种方式在运行时使用通用信息。 问题答案: 类型擦除不会擦除所有类型信息。它不会从类,字段,返回类型和参数定义中将其删除。保留以下示例中的类型信息: 这是可以通过反射实现的。您可以检查给定的是否是该类,将其强制转换为该类并获取类型信息。
问题内容: 我是从Joshua Bloch的google I / O困惑者演讲中得到的。这是代码 这个main方法会引发异常,因为它是原始类型,因此in中的所有泛型都将被删除,因此最终调用而不是。 我的问题是,即使我打电话是不是应该把它调用的方法,因为由于类型擦除,这种方法是有效的并且是类型的不是? 问题答案: 被调用的方法是在编译时定义的,而不是在运行时定义的。 如果在构造函数调用中添加参数,则
如何在不更改方法名称的情况下摆脱以下错误: 我的方法:
问题内容: 我的课是: 我在这个类中写一个子类: 注意在 覆盖类中 的 getX 方法时,我已经从方法定义中删除了该子句,现在它导致编译器出现异常行为,这是预期的: 不会如预期那样将其封闭在一个块中而无法编译。 编译而不将它封闭在一个块中。 但是下面的代码行需要try-catch块。 就像可以预见的那样,即在运行时多态期间使用父类引用来调用子方法,为什么Java的设计人员在覆盖特定的父类方法时没有
问题内容: 为什么在同一个类中使用以下两种方法是不合法的? 我得到了 方法add(Set)与类型Test中的另一个方法具有相同的擦除add(Set)。 虽然我可以解决它,但我想知道为什么javac不喜欢这样。 我可以看到,在很多情况下,这两种方法的逻辑非常相似,可以用一个方法代替 方法,但并非总是如此。 如果你想让两个带有这些参数,这会特别令人讨厌,因为那样你就不能只更改其中一个的名称。 问题答案