Tag: jls

带有接口类和类型变量的Java交集类型的限制

今天我尝试用一​​个使用交集类型的generics方法编写一个类,并根据相交的类型对不同的错误消息感到困惑。 假设我们有一个interface和一个class并在通用接口中定义generics方法: class ClassType { } interface InterfaceType { } interface I { public void foo(); public void foo1(); public void foo2(); public void foo3(); public void foo4(); public void foo5(); public void foo6(); public void foo7(); } 编译这会产生所有方法的错误,除了public void foo2(); 。 Main.java:8: error: repeated interface public void foo(); ^ Main.java:10: error: interface expected here […]

为什么一个类不能扩展枚举?

我想知道为什么在Java语言中一个class不能扩展enum 。 我不是在谈论扩展enum (由于java没有多重inheritance,而且enum隐式地扩展了java.lang.Enum ),因此无法完成enum ,但是按顺序extends enum的类只添加额外的方法,而不是额外的枚举值。 就像是: enum MyEnum { ASD(5), QWE(3), ZXC(7); private int number; private asd(int number) { this.number=number; } public int myMethod() { return this.number; } } class MyClass extends MyEnum { public int anotherMethod() { return this.myMethod()+1; } } 要像这样使用: System.out.println(MyClass.ASD.anotherMethod()); 那么,任何人都可以为此限制提供理由(或指向正确的JLS部分)吗?

“空语句”可能(不)抛出哪些Java错误和exception?

可以通过空语句抛出java.lang.Throwable 哪个子类? 用“空话”这句话,我指的是“没有”,“分号”和“半冒号”: // …. A(); B(); C(); try { // nothing } catch (java.lang.Throwable e) { // which Throwable subclass might we see? } D(); E(); F(); try { ; // semi-colon } catch (java.lang.Throwable e) { // which Throwable subclass might we see? } G(); H(); I(); try { ; ; ;; ;;;;; […]

类加载与类初始化

我一直认为类加载和类初始化是同义的,并且当初始化/加载的类以第一次以某种方式使用时,通常会按需发生。 但是现在我从这个答案中得知关于最终静态文件的行为,它保存了我认为错误的编译时常量。 请注意以下内容,非常清楚类加载和初始化是两种不同的机制。 作为一个侧面,请注意类加载和类初始化之间的区别:只有后者的出现由JLS精确指定。 类加载可以随时发生。 但有人可以解释Java语言中类加载和类初始化之间的区别。 通常直觉说初始化应始终先加载,但我完全错了。 可以在没有加载类的情况下进行初始化吗?

Java:编译时解析和“最具体的方法”,因为它适用于变量arity

有人可以帮助我理解JLS的第15.12.2.5节:最具体的方法吗? (随后是来自JLS的大胆剪切和粘贴) 另外,一个名为m的变量arity成员方法比另一个具有相同名称的变量arity成员方法更具体: 一个成员方法有n个参数,另一个成员方法有k个参数,其中n> = k。 第一个成员方法的参数类型是T1 ,. 。 。 ,Tn-1,Tn [],其他方法的参数类型是U1 ,. 。 。 ,Uk-1,英国[]。 如果第二种方法是通用的,那么让R1 … Rp p1成为它的forms类型参数,让Bl成为Rl的声明边界,1lp,让A1 … Ap成为推断的实际类型参数(§15.12.2.7)对于这种在初始约束条件下的调用Ti << Ui,1ik-1,Ti << Uk,kin和let Si = Ui [R1 = A1,…,Rp = Ap] 1ik; 否则让Si = Ui,1ik。 然后:对于从1到k-1的所有j,Tj <:Sj,并且对于从k到n的所有j,Tj <:Sk,并且,如果第二种方法是如上所述的通用方法,那么Al <:Bl [R1 = A1,…,Rp = Ap],1lp。 一个成员方法具有k个参数,另一个具有n个参数,其中n> = k。 第一种方法的参数类型是U1 ,. 。 。 ,Uk-1,Uk […]

为什么内部类不能使用静态初始化器?

Quoth JLS#8.1.3 : 内部类可能不会声明静态初始化器 (第8.7节 )…… 这表现如下: class A { class B { static { // Compile-time Error: Cannot define static initializer in inner type AB System.out.println(“Class is initializing…”); } } } 既然Java的内部(非静态)类是由类加载器加载的 ,就像其他类一样,为什么我们不能为它们安装静态初始化器? 这种限制背后的原因是什么?

非法的静态接口方法调用

Java-8允许在接口内部定义静态方法,但仅通过接口名称限制它的调用: 9.4:接口可以声明静态方法,这些方法在不引用特定对象的情况下被调用。 例如: interface X { static void y() { } } … X x = new X() {}; xy(); 导致错误: error: illegal static interface method call xy(); ^ the receiver expression should be replaced with the type qualifier ‘X’ 通常在JLS中,这种禁令有一个解释。 在这种情况下,我没有发现任何详细的信息。 所以我正在寻找对此规则的全面或权威解释:为什么禁止通过特定对象引用调用静态方法? 它打破了什么?

Java中保证了从左到右的操作顺序吗?

考虑这个function: public static final int F(int a, int b) { a = a – 1 + b; // and some stuff return a; } JVM的实现是否需要执行- 1 + b之前的- 1 ? 如果我们有一个连接到JVM的系统分析器,我们会看到在+ 1操作之前执行+ b操作吗?

为什么使用前缀增量被认为比构造标准中的后缀增量更好

我最近为Eclipse安装了Checkstyle插件,并且个人认为它非常棒。 但它给我的一个警告有点模糊。 确切的警告是“不允许使用++ ”。 它是关于某些行中的postfix ++ for(int i = 0; i < SOMETHING; i++) 好吧,我知道foreach是迭代的更好构造,但它无法在任何地方应用,有时候老式++是唯一的选择。 当我将行更改为 for(int i = 0; i < SOMETHING; ++i) 警告消失了。 我知道i++和++i之间的区别,在我生命的这一点上,我认为它们在标准构造方面可以互换。 但是Checkstyle认为i++有害(或容易出错)。 问题:为什么前缀增量优于构造中的后缀增量? 或者…… Checkstyle错了吗?

Javagenerics类型中的通配符参数在其范围内的正式条件是什么?

使用Java中的参数化类型,检查参数是否在其绑定工作中的规则如何完全针对通配符? 鉴于这样的类: class Foo {} 试验编译器接受的内容可以了解: 一个? extends 允许使用不相关的接口类型? extends通配符: Foo Foo有效 一个? extends 不允许使用不相关的类类型? extends通配符: Foo Foo无效。 这是有道理的,因为没有类型可以是Number和Thread的子类型 在一个? super ? super通配符,通配​​符的下限必须是类型变量的边界的子类型: Foo 不允许使用Foo因为Runnable不是Number的子类型。 同样,这种限制非常有意义。 但这些规则在哪里定义? 查看Java语言规范部分4.5 ,我没有看到任何区别于类的接口; 在应用我对JLS Foo解释Foo Foo据说是有效的。 所以我可能误解了一些东西。 这是我的尝试: 从JLS的那一部分: 参数化类型由类或接口名称C和实际类型参数列表组成。 如果C不是generics类或接口的名称,或者实际类型参数列表中的类型参数的数量与C的已声明类型参数的数量不同,则是编译时错误。在下文中,每当我们说话时除了明确排除之外,我们还包括类或接口类型的通用版本。 在本节中,让A1,…,An成为C的forms类型参数,并且让Bi为AI的声明边界。 符号[Ai:= Ti]表示用类型Ti替换类型变量Ai,对于1 <= i <= n,并且在整个说明书中使用。 令P = G 为参数化类型。 必须是这样的情况,在P经历捕获转换(第5.1.10节)之后导致类型G ,对于每个实际类型参数Xi,1 <= i <= n, Xi […]