标签: jls

具有固定/可变arity(varargs)匹配的最具体方法

Java语言规范的第15.12.2.5节中,它讨论了如何在具有固定arity的方法和可变arity方法(即varargs)中选择最具体的方法.

我在JLS中找不到的是关于两个方法之间的决定,其中一个是固定的arity,另一个是变量arity.例如:

public interface SomeApi {
    public String getSomething(String arg);       // method 1
    public String getSomething(String ... args);  // method 2
}
Run Code Online (Sandbox Code Playgroud)

按照人们的预期编译就好(由Yoni概述的原因如下).这个调用代码也编译:

SomeApi api = ...
Object o = api.getSomething("Hello");
Run Code Online (Sandbox Code Playgroud)

如果你运行它,method #1(即非varargs方法)被调用.为什么这个调用代码没有含糊不清?为什么固定arity方法比变量arity方法更具体?有人能指出我对规范的相关部分吗?

java variadic-functions jls

4
推荐指数
1
解决办法
1120
查看次数

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成为它的形式类型参数,让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 [],其他方法的参数类型是T1 ,. ..,Tn-1,Tn [].如果第二种方法是通用的,那么让R1 ... Rp p1成为它的形式类型参数,让Bl成为Rl的声明边界,1lp,让A1 ... Ap成为推断的实际类型参数(§15.12.2.7)对于这种在初始约束条件下的调用,Ui << Ti,1ik-1,Uk << Ti,kin和令Si = Ti [R1 = A1,...,Rp = Ap] 1in; 否则让Si = Ti,1in.然后:对于从1到k-1的所有j,Uj <:Sj,并且对于从k到n的所有j,Uk <:Sj,并且,如果第二种方法是如上所述的通用方法,则Al <:Bl [R1 = A1,...,Rp = Ap],1lp.

忽略问题泛型,这是否意味着varargs比子类型更重要,或者在确定一种方法是否比另一种更具体时,子类型比varargs更重要?我无法弄清楚. …

java variadic-functions jls

4
推荐指数
1
解决办法
785
查看次数

JLS如何与Sun javac对应/为什么不匹配

在Java中给出以下内容:

String a = "str";
CharSequence b = "charseq";
Run Code Online (Sandbox Code Playgroud)

你可以写

b = b + a;
Run Code Online (Sandbox Code Playgroud)

但无法编写(产生编译器错误)

b += a;
Run Code Online (Sandbox Code Playgroud)

错误是

incompatible types
found   : java.lang.CharSequence
required: java.lang.String
Run Code Online (Sandbox Code Playgroud)

现在在JLS第二版中,这可以通过15.26.2复合赋值运算符的这一行来解释:

All compound assignment operators require both operands to be of primitive type, except for +=, which allows the right-hand operand to be of any type if the left-hand operand is of type String.

但是在JLS第三版中,该注释消失了,关于复合运算符的唯一说明是在15.26.2复合赋值运算符

A compound assignment expression of the form E1 op= E2 is equivalent to E1 …

java javac jls

4
推荐指数
1
解决办法
201
查看次数

双重检查锁定的无序写入

在针对双重检查锁定方案的无序写入中提到的示例中(参考: IBM文章维基百科文章)

在构造函数完全初始化之前,我无法理解为什么Thread1会在同步块中出现的简单原因.根据我的理解,创建"new"和调用构造函数应该按顺序执行,同步锁不应该释放,直到所有工作都没有完成.

请让我知道我在这里缺少什么.

java multithreading synchronization jls double-checked-locking

4
推荐指数
1
解决办法
1071
查看次数

为什么JLS声明最大的int literal是2147483648?

JLS 3.10.1. Integer Literals http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.1陈述

The largest decimal literal of type int is 2147483648.
Run Code Online (Sandbox Code Playgroud)

同时这一行

int x = 2147483648;
Run Code Online (Sandbox Code Playgroud)

产生编译错误

The literal 2147483648 of type int is out of range
Run Code Online (Sandbox Code Playgroud)

JLS错了吗?

java jls

4
推荐指数
2
解决办法
230
查看次数

如何完全限定包名与本地成员名冲突的类?

好的,这里是JLS专家的一个非常好奇的Java 7语言谜题.以下代码不能用javac和Eclipse编译:

package com.example;

public class X {
    public static X com = new X();

    public void x() {
        System.out.println(com.example.X.com);
        // cannot find symbol  ^^^^^^^
    }
}
Run Code Online (Sandbox Code Playgroud)

似乎成员com完全阻止com.*从内部访问包X.然而,这并未得到彻底应用.以下工作,例如:

public void x() {
    System.out.println(com.example.X.class);
}
Run Code Online (Sandbox Code Playgroud)

我的问题:

  • 这种行为如何从JLS中证明是正确的?
  • 我该如何解决这个问题

注意,这只是对生成代码中的实际问题的简化,其中com.example.X需要完全限定并且com不能重命名成员.

更新:我认为它实际上可能是类似这样的问题:为什么我不能在Java中"静态导入"一个"等于"方法?

java visibility jls java-7

4
推荐指数
1
解决办法
586
查看次数

Java 8:接口成员的可访问性

无障碍

Java 8说:

缺少访问修饰符的接口的所有成员都是隐式公开的

Java 7说:

接口的所有成员都是隐式公共的.

当我尝试以下代码时:

public interface Test {
    protected int i = 10;
}
Run Code Online (Sandbox Code Playgroud)

编译,我得到了

Test.java:3: error: modifier protected not allowed here
        protected int i = 10;
                      ^

Java版本: Java(TM) SE Runtime Environment (build 1.8.0-b129)

但在上面的Interface成员声明我不缺乏访问修饰符,那么为什么我收到此错误.

java jls java-8

4
推荐指数
1
解决办法
1369
查看次数

为什么这个协变返回类型声明不会产生一个 unckecked 警告?

为什么以下代码不会产生编译时未经检查的警告:

class Parent {
    public List method(){
        return null;
    }
}

class Child extends Parent {

    public List<String> method() {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

而以下实际上是:

class Parent {
    public List<String> method(){
        return null;
    }
}

class Child extends Parent {

    public List method() {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

我实际上是在寻找 JLS 中这种行为的参考。

java jls covariant-return-types

4
推荐指数
1
解决办法
77
查看次数

Lambda私有方法的可访问性

我对以下情况感到困惑。

考虑两个包ab具有以下类:

1)MethodInvokercall()在给定对象上调用:

package b;
import java.util.concurrent.Callable;
public class MethodInvoker {
    public static void invoke(Callable r) throws Exception {
        r.call();
    }
}
Run Code Online (Sandbox Code Playgroud)

2)

package a;
import b.MethodInvoker;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
public class Test {

    private static Void method() {
        System.out.println("OK");
        return null;
    }

    public static void main(String[] args) throws Exception {
        Method method = Test.class.getDeclaredMethod("method");
        method.invoke(null);        // ok

        // TEST 1
        MethodInvoker.invoke(() -> {
            return method.invoke(null);  // ok (hmm....
        });

        // …
Run Code Online (Sandbox Code Playgroud)

java reflection lambda jls java-8

4
推荐指数
2
解决办法
2369
查看次数

java.lang.Double实现(Oracle JDK 1.8)中的不一致?

我查看了java.lang.Double该类的实现。的值NaN是的指定值0x7ff8000000000000L。将该public static final double NaN字段设置为该0.0d / 0.0值,以0x7ff8000000000000L判断JVM是否确实以这种方式实现了该字段。

  1. 为什么0x7ff8000000000000L选择此值()?这个值有什么特别的地方(例如它的位掩码)吗?

  2. 为什么将字段隐式设置为该值并取决于该0.0d / 0.0操作的基础实现,而静态方法public static long doubleToLongBits(double value)将该值显式设置0x7ff8000000000000LNaN参数的值?由于0.0d / 0.0高度依赖JVM的实现并在理论上可以更改(很可能永远不会更改),因此隐式设置它是否更安全?

这同样适用于POSITIVE_INFINITYNEGATIVE_INFINITY。字段被隐式设置为它们的值,但是某些方法使用显式指定的值。这背后有原因吗?

感谢您每天帮助我学习新知识:-)。

java double jls java-8

4
推荐指数
1
解决办法
91
查看次数