标签: jls

JLS和JSR以及JEP之间有什么区别

JLS - Java语言规范 - https://docs.oracle.com/javase/specs/jls/se9/html/index.html

JSR - Java规范请求 - https://jcp.org/aboutJava/communityprocess/final/jsr376/index.html(模块系统)正式文档,描述了用于添加到Java平台的建议规范和技术.

JEP - JDK增强提案- http://openjdk.java.net/jeps/0,http://openjdk.java.net/jeps/261(模块系统)

这三者有什么区别?

java jsr jls jep

17
推荐指数
1
解决办法
2379
查看次数

在子类构造函数中调用getClass()总是安全的吗?

关于类加载的文章指出getClass()不应该在构造函数中调用该方法,因为:

对象初始化仅在构造函数代码的出口处完成.

他们给出的例子是:

public class MyClassLoader extends ClassLoader{
    public MyClassLoader(){
        super(getClass().getClassLoader()); // should not call getClass() because object
                                            //    initialization will be complete only at
                                            //    the exit of the constructor code.
    }
}
Run Code Online (Sandbox Code Playgroud)

但是据我所知,本机final方法getClass()将始终返回该java.lang.Class对象实例的对象,无论它在何处被调用(在构造函数内或不在构造函数内).

将调用getClass()构造函数中曾经给我们带来的问题?

如果是这样,getClass()在构造函数中调用会给我们带来错误的一些例子是什么?

java constructor class classloader jls

16
推荐指数
1
解决办法
2022
查看次数

什么是Java中的捕获转换,谁能给我举例?

我注意到JLS谈到5.1.10捕获转换,但我不明白它们是什么.

任何人都可以向我解释/举例吗?

java capture jls

15
推荐指数
2
解决办法
9465
查看次数

Java8中的模糊过载 - 是ECJ还是javac对吗?

我有以下课程:

import java.util.HashSet;
import java.util.List;

public class OverloadTest<T> extends  HashSet<List<T>> {
  private static final long serialVersionUID = 1L;

  public OverloadTest(OverloadTest<? extends T> other) {}

  public OverloadTest(HashSet<? extends T> source) {}

  private OverloadTest<Object> source;

  public void notAmbigious() {
    OverloadTest<Object> o1 = new OverloadTest<Object>(source);
  }

  public void ambigious() {
    OverloadTest<Object> o2 = new OverloadTest<>(source);
  }
}
Run Code Online (Sandbox Code Playgroud)

这在JDK 7的javac以及eclipse(兼容性设置为1.7或1.8)下编译得很好.但是,尝试在JDK 8的javac下编译,我收到以下错误:

[ERROR] src/main/java/OverloadTest.java:[18,35] reference to OverloadTest is ambiguous
[ERROR] both constructor <T>OverloadTest(OverloadTest<? extends T>) in OverloadTest and constructor <T>OverloadTest(java.util.HashSet<? extends T>) in OverloadTest match …
Run Code Online (Sandbox Code Playgroud)

java eclipse javac jls ecj

15
推荐指数
1
解决办法
755
查看次数

Java final 字段:当前 JLS 是否可能出现“污点”行为

我目前正在尝试了解有关最终字段的 JLS 部分

为了更好地理解 JLS 中的文本,我还在阅读Jeremy Manson(JMM 的创建者之一)撰写的The Java Memory Model

该论文包含让我感兴趣的示例:如果o具有 final 字段的对象对另一个线程可见t两次:

  • o的构造函数完成之前首先“不正确地”
  • o的构造函数完成后的下一个“正确”

然后即使仅通过“正确”发布的路径访问它,也t可以看到半构造的o

这是论文中的部分:

图 7.3:简单最终语义示例

f1 是最后一个字段;它的默认值为 0

主题 1 主题 2 主题 3
o.f1 = 42;
p = o;
freeze o.f1;
q = o;

Run Code Online (Sandbox Code Playgroud)
r1 = p;
i = r1.f1;
r2 = q;
if (r2 == r1)
    k = r2.f1;
Run Code Online (Sandbox Code Playgroud)
r3 = q;
j = r3.f1;



Run Code Online (Sandbox Code Playgroud)

我们假设 r1、r2 和 …

java multithreading final java-memory-model jls

15
推荐指数
2
解决办法
684
查看次数

是否应在Java 1.8下编译以下代码

给出以下课程:

public class FooTest {

    public static class Base {
    }

    public static class Derived extends Base {
    }

    public interface Service<T extends Base> {
        void service(T value);
    }

    public abstract class AbstractService<T extends Derived> implements  Service<T> {
        public void service(T value) {
        }
    }

    private AbstractService service;

    public void bar(Base base) {
        if(base instanceof Derived) {
            service.service(base); // compile error at this line
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用以下内容构建类时pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mgm-tp</groupId>
    <artifactId>java-compiler-test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <build> …
Run Code Online (Sandbox Code Playgroud)

java eclipse jls language-lawyer java-8

14
推荐指数
1
解决办法
1015
查看次数

Java SE 11 - Java 语言规范中类型转换的新案例

Java SE 11 的JLS §5.2包含一些 Java 8 的 JLS 没有的新类型转换案例,请参阅列表中的第 4 项和第 5 项:

赋值上下文允许使用以下之一:

  1. 身份转换
  2. 扩大原始转换
  3. 扩大参考转换
  4. 一个扩大的参考转换,然后是一个拆箱转换
  5. 扩展引用转换,然后是拆箱转换,然后是扩展基元转换
  6. 拳击转换
  7. 一个装箱转换,然后是一个扩大的参考转换
  8. 拆箱转换
  9. 一个拆箱转换,然后是一个扩大的原始转换

我不明白列表中的案例 4案例 5。谁能用例子给我一些解释?如果可能,还请说明其实际用途。


更新:

正如@Naman 所评论的,这里是更改 JLS 的提议 - JDK-8166326:5.2:允许在拆箱前加宽,这是自 Java-9 以来生效的。在报告中,它提到:

这种行为对于与 capture 的互操作性尤其重要各种现有程序都希望能够将 a 的元素List<? extends Integer>视为整数。

List<? extends Integer> li = null;
int i = li.get(0);
Run Code Online (Sandbox Code Playgroud)

这可能暗示着这次 JLS 的改变确实有实际的必要性。但我还是不明白为什么 <? extends Integer> 很重要。什么是与捕获的互操作性意味着,它为什么如此重要?这些现有的各种程序是什么样的?它们是 Java …

java autoboxing type-conversion jls java-11

14
推荐指数
1
解决办法
241
查看次数

Java:重载方法解析和varargs - 令人困惑的例子

正当我认为我理解JLS15.12应用于varargs时,这是这个例子:

package com.example.test.reflect;

public class MethodResolutionTest2 {
    public int compute(Object obj1, Object obj2) {
        return 42;
    }   
    public int compute(String s, Object... objects)
    {
        return 43;
    }

    public static void main(String[] args) {
        MethodResolutionTest2 mrt2 = new MethodResolutionTest2();
        System.out.println(mrt2.compute("hi",  mrt2));  
        System.out.println(mrt2.compute("hi",  new Object[]{mrt2}));    
        System.out.println(mrt2.compute("hi",  new Object[]{mrt2, mrt2, mrt2}));
    }
}
Run Code Online (Sandbox Code Playgroud)

打印出来的

42
43
43
Run Code Online (Sandbox Code Playgroud)

我理解第一行:JLS15.12表示方法解决是分阶段进行的,而第1阶段和第2阶段忽略了varargs方法,以确定是否存在兼容方法,仅当阶段1和阶段2失败时才会发生阶段3(包括变量).(参见JLS和这个问题.)compute(String s, Object... objects)如果compute(Object obj1, Object obj2)适用,总是被忽略.

但我不明白为什么43为其他两行打印.An Object[]也是一个实例Object,为什么它与varargs方法匹配?


编辑:

...还有这个

Object arg2 …
Run Code Online (Sandbox Code Playgroud)

java variadic-functions jls

13
推荐指数
1
解决办法
2168
查看次数

关于在对象的构造函数完成之前对对象的引用

你们每个人都知道JMM的这个特性,有时候对象的引用可以完成这个对象的构造函数之前获得值.

JLS7中,p.17.5 最后的字段语义我们也可以阅读:

final字段的使用模型很简单:final在该对象的构造函数中设置对象的字段; 并且在对象的构造函数完成之前,不要在另一个线程可以看到的地方写入对正在构造的对象的引用.如果遵循这一点,那么当另一个线程看到该对象时,该线程将始终看到该对象的final字段的正确构造版本.(1)

在JLS之后,接下来的示例演示了如何不保证非最终字段的初始化(1Example 17.5-1.1) (2):

class FinalFieldExample { 
    final int x; 
    int y; 

    static FinalFieldExample f;

    public FinalFieldExample() { 
        x = 3; 
        y = 4; 
    } 

    static void writer() { 
        f = new FinalFieldExample(); 
    } 

    static void reader() { 
       if (f != null) { 
           int i = f.x; // guaranteed to see 3 
           int j = f.y; // could …
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading final jls

13
推荐指数
1
解决办法
2061
查看次数

最终字段的初始化顺序

考虑这两个类:

public abstract class Bar {
    protected Bar() {
        System.out.println(getValue());
    }

    protected abstract int getValue();
}

public class Foo extends Bar {
    private final int i = 20;

    public Foo() {
    }

    @Override
    protected int getValue() {
        return i;
    }

    public static void main(String[] args) {
        new Foo();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我执行Foo,则输出为20.

如果我使字段非final,或者我在Foo构造函数中初始化它,则输出为0.

我的问题是:在最终字段的情况下,初始化顺序是什么?JLS中描述了这种行为?

我希望找到最终的领域一些特殊的规则在这里,但除非我错过了什么,没有.

请注意,我知道我永远不应该从构造函数中调用可覆盖的方法.这不是问题的关键.

java constructor final jls

13
推荐指数
2
解决办法
1090
查看次数