Oracle 在http://docs.oracle.com/javase/specs/ 上有最新版本的 java 规范,但我找不到旧版本。这些存档在任何地方吗?
我正在尝试一些C#代码的Java端口,我很惊讶地看到javac 1.8.0_60 getfield每次访问一个对象字段时都会发出操作码.
这是Java代码:
public class BigInteger
{
private int[] bits;
private int sign;
//...
public byte[] ToByteArray()
{
if (sign == 0)
{
return new byte[] { 0 };
}
byte highByte;
int nonZeroDwordIndex = 0;
int highDword;
if (bits == null)
{
highByte = (byte)((sign < 0) ? 0xff : 0x00);
highDword = sign;
}
else if (sign == -1)
{
highByte = (byte)0xff;
assert bits.length > 0;
assert bits[bits.length - 1] != 0;
while …Run Code Online (Sandbox Code Playgroud) 我已经在某个服务器类型的应用程序上工作了一段时间,我发现它的设计挑战了我在 Java 中看待内存一致性(可以这么说)的方式。
\n\n该应用程序使用 NIO,因此 I/O 线程数量有限(它们只执行网络 I/O,不执行其他操作;它们永远不会终止,但可能会被阻塞以等待更多工作)。
\n\nClientCon每个连接在内部都表示为特定类型的对象,在本示例中我们称其为特定类型的对象。ClientCon有各种与会话相关的字段,这些字段都不是易失性的。不存在与获取/设置这些字段的值相关的任何类型的同步。
接收到的数据由具有固定最大大小的逻辑单元组成。每个这样的单元都有一些允许决定处理类型(类)的元数据。一旦完成,就会创建该类型的新对象。所有此类处理程序都有字段,但这些字段都不是易失性的。然后,I/O 线程(为每个线程分配一个具体的 I/O 线程ClientCon)protected在新处理程序对象上调用剩余缓冲区内容(在读取元数据之后)的 read 方法。
之后,相同的处理程序对象被放入一个特殊的队列中,然后将该队列(队列)提交给线程池执行(其中调用每个处理程序的 run 方法以根据读取的数据采取操作)。对于这个例子,我们可以说 TP 线程永远不会终止。
\n\n因此,TP 线程将获得它以前从未访问过的对象。该对象的所有字段都是非易失性的(并且大多数/全部都是非最终的,因为它们是在构造函数外部修改的)。
\n\n处理程序的运行方法可以基于会话特定字段进行操作,ClientCon也可以设置它们和/或对处理程序对象自己的字段进行操作,这些字段的值在读取方法中设置。
根据 CPJ(Java 并发编程:设计和原理):
\n\n\n\n\n\n\n线程第一次访问对象的字段时,它会看到该字段的初始值或自其他线程写入以来的值。
\n
class FinalFieldExample { \n final int x;\n int y; \n static FinalFieldExample f;\n\n public FinalFieldExample() {\n x = 3; \n …Run Code Online (Sandbox Code Playgroud) 今天,我尝试编写一个具有使用交集类型的泛型方法的类,并被根据相交类型的不同错误消息弄糊涂了。假设我们有 aninterface和 aclass并在泛型接口中定义泛型方法:
class ClassType {
}
interface InterfaceType {
}
interface I<T> {
public <X extends InterfaceType & InterfaceType> void foo();
public <X extends ClassType & ClassType> void foo1();
public <X extends ClassType & InterfaceType> void foo2();
public <X extends InterfaceType & ClassType> void foo3();
public <X extends T & ClassType> void foo4();
public <X extends ClassType & T> void foo5();
public <X extends InterfaceType & T> void foo6();
public <X extends T & InterfaceType> …Run Code Online (Sandbox Code Playgroud) 我在某些 StackOverflow 答案中看到了术语抽象方法、具体方法 和默认方法的“不同”定义。
Java 语言规范给出的真正定义是什么?请在您的答案中包含相关的支持 JLS 参考。
在查看Java 调用动态文档时,我看到了以下 Java 特性示例,称为“exotic identifiers”:
int #"strange variable name" = 42;
System.out.println(#"strange variable name"); // prints 42
Run Code Online (Sandbox Code Playgroud)
我无法让它在我的机器上的 openjdk8 上工作。进一步的谷歌搜索发现了一些与此功能相关的错误报告,但没有其他太多。特别是这个错误,以及这个其他错误。
这里的另一个错误表明此功能已在 jdk7 中删除/从未删除。
这是以前的 Java 功能,后来被删除了,还是从来没有正式的 Java 功能?这会被添加回来吗?
语言规范中专门针对 Java 内存模型 (JMM) 的部分(链接)多次提到“执行跟踪”。
例如从一开始:
给定一个程序和该程序的执行跟踪,存储器模型描述该执行跟踪是否是该程序的合法执行。Java 编程语言内存模型的工作原理是检查执行跟踪中的每次读取,并根据特定规则检查该读取观察到的写入是否有效。
但我找不到这个术语的任何描述/定义。
那么,JMM 中的“执行跟踪”到底是什么?它到底由什么组成?
最受欢迎的是对语言规范文本中特定位置的引用。
Java 语言规范 20,第4.10 节。子类型表明
类型 T 的子类型都是类型 U,因此 T 是 U 的超类型和 null 类型。我们写 T
<:S 来表示类型 T 和 S 之间存在子类型关系。
这是否意味着 null 类型是所有基本类型的子类型?如果是的话,有什么实际后果吗?
我正在编写一个库来解析和分析 java 代码,那么我应该将其视为null的子类型吗int?或者根本不重要?
我一直想知道Java泛型的一些奇怪方面和通配符的使用.比方说,我有以下API:
public interface X<E> {
E get();
E set(E e);
}
Run Code Online (Sandbox Code Playgroud)
然后,假设我们声明了以下方法:
public class Foo {
public void foo(X<?> x) {
// This does not compile:
x.set(x.get());
}
public <T> void bar(X<T> x) {
// This compiles:
x.set(x.get());
}
}
Run Code Online (Sandbox Code Playgroud)
从我的"直觉"的理解,X<?>实际上是一样的X<T>,只是未知<T>是正式未知的客户端代码.但在内部foo(),我猜测编译器可以推断(伪JLS代码)<T0> := <?>[0], <T1> := <?>[1], etc....这是大多数程序员明确而直观地做的事情.他们委托私人助手方法,导致许多无用的锅炉板代码:
public class Foo {
public void foo(X<?> x) {
foo0(x);
}
private <T> void foo0(X<T> x) {
x.set(x.get());
}
}
Run Code Online (Sandbox Code Playgroud)
另一个例子: …