如果我将变量声明为其抽象超类,则在Javac中将忽略Scala的@throws批注

2rs2ts

在Java中,throws如果原始抽象方法没有(overridden method does not throw Exception。),则不能指定重写的抽象方法某些异常。但是在Scala中,您可以这样做,因为它没有检查的异常。很好,但是如果您使用的@throws注释应该使Java编译器了解发生了什么,对吗?

鉴于此Scala代码:

package myscala

abstract class SFoo {
    def bar(): Unit
}

class SFoobar extends SFoo {
    @throws[Exception]
    override def bar(): Unit = {
        throw new Exception("hi there")
    }
}

我有两个不同的Java程序,其中一个将Exception在运行时编译并运行到一个,而另一个将不编译。

编译:

import myscala.SFoo;
import myscala.SFoobar;

public class Foobar {
    public static void main(String[] args) {
        SFoo mySFoo = new SFoobar();
        mySFoo.bar();
    }
}

不编译(unreported exception Exception; must be caught or declared to be thrown):

import myscala.SFoo;
import myscala.SFoobar;

public class Foobar {
    public static void main(String[] args) {
        SFoobar mySFoo = new SFoobar();       // only difference is the declared type
        mySFoo.bar();
    }
}

我真的不明白。为什么Java编译器不接受我声明SFoobar.bar即使Foo.bar没有这样的声明也会引发异常的事实,并因此引发类似的编译错误?

有翼的潜艇

如果转换斯卡拉代码SFooSFooBar以等效的Java代码:

abstract class SFoo {
    void bar() {}
}

class SFoobar extends SFoo {
    void bar() throws Exception {
        throw new Exception("hi there");
    }
}

它不能编译,因为:

error: bar() in SFoobar cannot override bar() in SFoo
        void bar() throws Exception {
             ^
  overridden method does not throw Exception

Java强制执行以下规则:重写方法不能抛出被其重写的方法未抛出的异常。这使得检查时向上转型,如转换时的异常类型安全的SFooBar一个SFoo

如果并且已经用Java定义,则您对FooBar类的第一个定义(将anSFooBar存储在SFoo变量中)将是绝对安全的Java编译器知道an not throw ,并假设已遵守重写方法的规则,因此在此不做任何额外的检查。SFooSFooBarSFoo.barException

但是,Scala编译器不在乎此规则是否适用于重写方法,而是可以让您打破这种类型的安全性。Java编译器忽略了这一事实,因此会生成在运行时中断的代码。Java和Scala之间的不匹配是任何编译器都无法解决的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在抽象类中将方法声明为可选方法

为什么我必须在抽象类中将字段声明为“公共”才能从派生类访问它?

如果我将类声明为const ...而不是constexpr,程序将无法正常工作?

在类中将数组的容量声明为它自己的变量的好处?

如果我将向量声明为全局变量,那么向量在哪里分配?

如何将变量声明为函数并为其赋值

我们可以将JPA静态元模型类的成员变量声明为final吗?

如何强制实现抽象类的类声明其变量?

如果我只有一个静态变量的类-我应该将该类声明为静态的吗?

如果将一个类声明为final,则必须将这些方法声明为final

Matlab:当实现在超类中声明为抽象的方法时,为什么必须公开访问?

如果虚方法被声明为抽象

C ++:使用auto将类声明为函数内的变量

Scala类成员导致错误“类'class'必须声明为抽象或实现成员'member'”

类必须声明为抽象或实现convertToLegacyCheckingEqualizer

为什么HttpServlet类被声明为抽象的?

我可以将方法声明为带有lombok批注的toString

将 eval() 声明为变量

如果我的类是文字类,那么将我的类的对象声明为constexpr是否多余?

为什么将接口声明为抽象?

在c中将函数声明为变量

类必须声明为抽象或实现抽象方法toArray

类必须声明为抽象或实现抽象方法错误

类必须声明为抽象或实现抽象方法

“ SessionTrigger”类必须声明为抽象或实现抽象成员

类必须声明为抽象或实现抽象方法:Intellij错误?

将接口声明为其类型

无法将变量“pdu”声明为抽象类型“Tins::PDU”

错误:无法将变量“t”声明为抽象类型“T”