我们有一些单元测试可以在Eclipse 3.4中编译和运行,但是当我们尝试使用javac编译它们时,它会失败.我已经设法将代码缩减为小而自包含的东西,因此它没有外部依赖性.代码本身没有多大意义,因为它完全脱离了上下文,但这并不重要 - 我只需要找出为什么javac不喜欢这个:
public class Test {
public void test() {
matchOn(someMatcher().with(anotherMatcher()));
}
void matchOn(SubMatcher matcher) {}
SubMatcher someMatcher() {
return new SubMatcher();
}
Matcher anotherMatcher() {
return null;
}
}
interface Matcher <U, T> {}
class BaseMatcher implements Matcher {
public BaseMatcher with(Matcher<?,?> matcher) {
return this;
}
}
class SubMatcher extends BaseMatcher {
@Override
public SubMatcher with(Matcher matcher) {
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
我试着JDK 1.5.0_10和1.6.0_13,与相同的结果:
Test.java:6: matchOn(test.SubMatcher) in test.Test cannot be applied to …Run Code Online (Sandbox Code Playgroud) 在Java中就是这种情况:
public void method() {
if (condition) {
Object x = ....;
}
System.out.println(x); // Error: x unavailable
}
Run Code Online (Sandbox Code Playgroud)
我想知道的是:事实x是否仅限于if-statement 的范围只是Java编译器的一个特性,或者x实际上是在if-statement 之后从堆栈中删除了?
当我尝试在/减量中写一个后缀/前缀,然后在/减量中写一个post /前缀时,我得到以下错误:操作++/ - 的参数无效.
但是,据JLS称:
PostIncrementExpression:
PostfixExpression ++
Run Code Online (Sandbox Code Playgroud)
和
PostfixExpression:
Primary
ExpressionName
PostIncrementExpression
PostDecrementExpression
Run Code Online (Sandbox Code Playgroud)
所以写:
PostfixExpression ++ ++
Run Code Online (Sandbox Code Playgroud)
应该可能......有什么想法吗?
以下Java代码生成以下JVM字节码.
我很好奇为什么生成从偏移31到偏移36的代码.JLS7或JVM7规范中没有任何内容涉及此问题.我错过了什么吗?
即使我删除了println语句,代码(偏移31到偏移36)仍然只在较早的位置生成,因为println调用已被删除.
// Java code
void testMonitor() {
Boolean x = new Boolean(false);
synchronized(x) {
System.out.println("inside synchronized");
System.out.println("blah");
};
System.out.println("done");
}
// JVM bytecode
Offset Instruction Comments (Method: testMonitor)
0 new 42 (java.lang.Boolean)
3 dup
4 iconst_0
5 invokespecial 44 (java.lang.Boolean.<init>)
8 astore_1 (java.lang.Boolean x)
9 aload_1 (java.lang.Boolean x)
10 dup
11 astore_2
12 monitorenter
13 getstatic 15 (java.lang.System.out)
16 ldc 47 (inside synchronized)
18 invokevirtual 23 (java.io.PrintStream.println)
21 getstatic 15 (java.lang.System.out)
24 ldc 49 (blah)
26 invokevirtual 23 …Run Code Online (Sandbox Code Playgroud) 是否真的可以在构造函数中创建的线程中查看部分构造的对象,因为缺少同步和泄漏此实例?
当然,除了有子类的情况,或者我们正在使用clone或类似的东西进行隐式构造 - 所以让我们假设该类是final,并且在调用其他线程之前调用构造函数的线程中它是完全初始化的.
据我所知,以下hb()规则适用,
线程中的每个操作都发生在该程序顺序中稍后出现的该线程中的每个操作之前(程序顺序规则)
在启动线程中的任何操作之前,对线程的start()调用发生.
如果是hb(x,y)和hb(y,z),那么hb(x,z)
那么它是否意味着以下代码在技术上是线程安全的(我从类似的问题中得到它为什么我不应该在我的类的构造函数中使用Thread.start()?,还有一个类似的问题为什么它是坏的练习在构造函数上创建一个新线程?,ps我希望这个不会被重复关闭)
final class SomeClass
{
public ImportantData data = null;
public Thread t = null;
public SomeClass(ImportantData d)
{
t = new MyOperationThread();
// t.start(); // Footnote 1
data = d;
t.start(); // Footnote 2
}
}
Run Code Online (Sandbox Code Playgroud)
PS显然数据字段在这里缺乏封装,但是这个问题是关于对象从线程t的状态可见性.
考虑以下简化的测试用例:
import java.util.AbstractList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
public final class Example {
static class PairList<A, B> {
public void replaceAllSecond(Function<? super B, ? extends B> secondFunction) {}
public void replaceAllSecond(BiFunction<? super A, ? super B, ? extends B> secondFunction) {}
}
static class ImmutableList<E> extends AbstractList<E> {
public static <E> ImmutableList<E> copyOf(Iterable<? extends E> elements) {return null;}
public static <E> ImmutableList<E> copyOf(Collection<? extends E> elements) {return null;}
public static <E> ImmutableList<E> copyOf(Iterator<? extends E> …Run Code Online (Sandbox Code Playgroud) 我有以下课程:
public abstract Foo {
Foo() {}
public abstract Foo doSomething();
public static Foo create() {
return new SomePrivateSubclassOfFoo();
}
}
Run Code Online (Sandbox Code Playgroud)
我想将其更改为以下定义:
public abstract Foo<T extends Foo<T>> {
Foo() {}
public abstract T doSomething();
public static Foo<?> create() {
return new SomePrivateSubclassOfFoo();
}
}
Run Code Online (Sandbox Code Playgroud)
此更改二进制兼容吗?即,针对旧版本的类编译的代码是否可以使用新版本而无需重新复制?
我知道我需要改变SomePrivateSubclassOfFoo,这没关系.我也知道,当编译旧客户端代码时,此更改将触发有关原始类型的警告,这对我也是可以的.我只是想确保不需要重新编译旧的客户端代码.
从我的理解,这应该是好的,因为擦除T是Foo,这样的签名doSomething在字节码是和以前一样.如果我看一下印刷的内部类型签名javap -s,我确实看到了这个确认(虽然打印的"非内部"类型签名没有-s做不同).我也测试了这个,它对我有用.
但是,Java API Compliance Checker告诉我这两个版本不是二进制兼容的.
什么是正确的?JLS是否保证二进制兼容性,或者我在测试中是否幸运?(为什么会发生这种情况?)
在阅读有关类加载器的内容时,我遇到了二进制名称的概念,但我不太理解它。
您能否解释一下 java 类的二进制名称是什么以及为什么 package + className 不够(我猜是因为内部类,但这是唯一的原因)?谢谢
(我知道该领域的先前问题,但您会注意到原始发帖者问题的根源从未得到解决。我的问题和他们的问题一样,本质上是符号性的。)
\n在 Java 语言规范第 11 版中(但有趣的是 JLS 17 中不再出现,可能是因为它很难理解),它在第 4.10.2 节中部分写道:
\n\n\n给定泛型类型声明 C<F\xe2\x82\x81,\xe2\x80\xa6,F\xe2\x82\x99> ( n > 0),参数化类型 C<T\xe2\x82 的直接超类型\x81,\xe2\x80\xa6,T\xe2\x82\x99>,其中 T\xe1\xb5\xa2 (1 \xe2\x89\xa4 i \ xe2\x89\xa4 n ) 是一种类型,都是以下的:
\nD<U\xe2\x82\x81\xce\xb8,\xe2\x80\xa6,U\xe2\x82\x96\xce\xb8>,其中 D<U\xe2\x82\x81,\xe2\x80\ xa6,U\xe2\x82\x96> 是泛型类型,它是泛型类型 C<F\xe2\x82\x81,\xe2\x80\xa6,F\xe2\x82\x99> 的直接超类型和 \ xce\xb8 是替换 [F\xe2\x82\x81:=T\xe2\x82\x81,\xe2\x80\xa6,F\xe2\x82\x99:=T\xe2\x82\x99]。
\n
以下是我所做的假设(可能是不正确的!):
\npublic interface Collection<E> extends Iterable<E>( n = 1),而 C<T\xe2\x82\x81,\xe2\x80 \xa6,T\xe2\x82\x99> 表示public class MyStringCollection implements Collection<String> …有人可以解释JLS§8.4.8.4中提到的"严格的默认 - 抽象和默认 - 默认冲突规则" .
它们是在JLS中定义的吗?我似乎无法找到他们的定义.
java ×10
jls ×10
java-8 ×2
classloader ×1
concurrency ×1
decrement ×1
generics ×1
increment ×1
inheritance ×1
java-11 ×1
javac ×1
jvm ×1
scope ×1
stack ×1