为什么';Java不支持通用的一次性软件吗?
当然,我们没有它也能过得去。我并不是要求我们能够在相同的为什么';Java不支持通用的一次性软件吗?,java,generics,oop,throwable,Java,Generics,Oop,Throwable,当然,我们没有它也能过得去。我并不是要求我们能够在相同的try块中执行catch Bouncy和Bouncy,但是如果我们在不相交的上下文中使用它们,并且有严格的编译时可执行规则(这与泛型现在的工作方式非常相似),那么这不是可行的吗?Java语言规范 : 由于Java虚拟机的捕获机制仅适用于非泛型类,因此需要此限制 就我个人而言,我认为这是因为在catch子句中我们无法获得泛型的任何好处。由于类型擦除,我们无法编写catch(Bouncy-ex),但是如果我们编写catch(Bouncy-ex)
try
块中执行catch Bouncy
和Bouncy
,但是如果我们在不相交的上下文中使用它们,并且有严格的编译时可执行规则(这与泛型现在的工作方式非常相似),那么这不是可行的吗?Java语言规范
:
由于Java虚拟机的捕获机制仅适用于非泛型类,因此需要此限制
就我个人而言,我认为这是因为在
catch
子句中我们无法获得泛型的任何好处。由于类型擦除,我们无法编写catch(Bouncy-ex)
,但是如果我们编写catch(Bouncy-ex)
,那么将其设置为泛型将毫无用处。类型擦除。运行时异常类型没有泛型信息。因此你不能做
void process(List<String> list) {
}
void process(List<Integer> list) {
}
当Java从1.4迁移到1.5时,类型擦除是如何决定保持向后兼容性的。当时很多人都不快乐,这是理所当然的。但考虑到已部署代码的数量,打破1.4中运行良好的代码是不可想象的。以下是您可以做的几件事:
界面弹性{
/…
}
类BouncyString扩展异常实现弹性{
/…
}
抛出
子句可以引用类型参数,例如。
静态无效
throwIfInstanceOf(Throwable ex,Class clazz)抛出X{
if(clazz.isInstance(ex))抛出clazz.cast(ex);
}
简短回答:因为他们走捷径,就像他们在擦除时做的那样 长答案:正如其他人已经指出的,由于擦除,在运行时“catch MyException”和“catch MyException”之间没有区别 但是这并不意味着不需要一般异常。我希望泛型能够使用泛型字段!它们可以只允许泛型异常,但只允许在原始状态下捕获它们(例如“catch MyException”) 当然,这将使泛型更加复杂。
这是为了说明删除泛型的决定有多糟糕。什么时候我们会有一个支持真正泛型(使用RTTI)的Java版本,而不是当前的语法糖?您仍然可以使用泛型方法,如下所示:
catch( Mistake ea ) {
...
}
因为这行不通:
catch (Exception<T1> e) {}
Java本可以毫无问题地完成整个过程:
class MyException<T> {}
...
catch (MyException e) { // raw
类MyException{}
...
捕获(MyException e){
知道为什么会这样吗?抱歉,但我不能完全理解JLS中的参数。好像这条语句忘记了编译器执行类型擦除,在JVM使用其捕获机制时有效地删除了泛型。那么,如果语法糖没有impa,那么如何避免语法糖呢因为它将被删除,所以在运行时使用ct?在这种情况下,为什么不禁止下面我自己的答案中的例子呢?我的意思是,JVM在这些上下文中也不支持泛型,但它们在源代码中是允许的。:)感谢您承认“类型擦除后冲突”中的弱点论点——我觉得它太容易被接受为限制的原因,所以我自己承担起了抗争的责任。当然,这也意味着被接受的答案也是误导性的,可能需要更正。我的一些例子可能会让人困惑。当我给出两个方法签名的例子时,它们会删除到同一个签名e、 我引用了一些真实的例子,如果出现无效的情况,兼容编译器必须拒绝编译。我只是指出这些情况(对相同泛型类型的擦除)语言设计者没有将它们作为全面禁止泛型的前提,但它们似乎被用来禁止抛出子句中的泛型。相反,编译器被要求识别并报告此类情况。它本可以对catch子句执行相同的操作。选择似乎是任意的。语句“catch(Foo-ex)”大约在“if-ex-instanceof-Foo”;类型擦除使得无法将其与“if-ex-instanceof-Foo”区分开来。虽然列表和列表在运行时与非泛型API配合很好;但在编译时类型信息尚未擦除,因此允许泛型返回或设置。我相信您的前提是有缺陷的。为什么catch(Foo-ex)
需要解释为if(ex instanceof Foo)
?编译器可以执行类型擦除,运行时将捕获解释为if(ex instanceof Foo)
。运行时将像今天一样工作,但由于一般异常,我们将有更好的编译时支持。当然,在同一上下文中不可能同时捕获Foo
和Foo
,但这没关系:今天的方法参数也一样糟糕,因为不能同时捕获Foo(列表)
和foo(List)
在相同的上下文中。是的,不可能区分foo和foo,这是不正常的。当我捕获IOException时,我只想捕获它,而不是IOException。现在使用的解决方法是有特定的异常(FileNotFound,ReadTimeout)如果需要,可以分别捕获它们中的每一个。通过向我们展示一个使用标准异常类的精心设计的示例,您坚持认为在异常类中支持泛型需要运行时泛型。如果Java支持泛型异常——对我来说很明显,在理论上支持这些——我们将泛型类型参数用于更普通的事情。您必须开始了解泛型的含义:语法suga
public class SomeException {
private final Object target;
public SomeException(Object target) {
this.target = target;
}
public <T> T getTarget() {
return (T) target;
}
}
....
catch (SomeException e) {
Integer target = e.getTarget();
}
catch (Exception<T1> e) {}
List<T1> list;
catch (Exception<T1> e) {}
catch (Exception<T1> e) {}
catch (Exception<T2> e) {}
interface MyInterface {
Comparable<Integer> getComparable();
}
interface MyInterface {
Comparable<Integer> getComparable();
Comparable<String> getComparable();
}
interface MyInterface {
void setComparable(Comparable<Integer> comparable);
}
interface MyInterface {
void setComparable(Comparable<Integer> comparable);
void setComparable(Comparable<String> comparable);
}
class MyException<T> {}
...
catch (MyException e) { // raw
class MyException<T> {}
...
catch (MyException<Foo> e) {