包装类的缺点很少.需要注意的是,包装类不适合在回调框架中使用,其中对象将自引用传递给其他对象以进行后续调用("回调").因为包装对象不知道它的包装器,它会传递对它自己的引用(this),并且回调会逃避包装器.
有人可以用一个例子来解释这意味着什么.它是用Effective Java编写的,但我并没有完全理解它.
要添加到上下文,而不是继承,我们应该支持组合,而不是导致子类,Set我们应该使用这样的东西:
public class ForwardingSet<E> implements Set<E> {
private final Set<E> s;
public ForwardingSet(Set<E> s) { this.s = s; }
public void clear() { s.clear(); }
public boolean contains(Object o) { return s.contains(o); }
...
}
Run Code Online (Sandbox Code Playgroud)
但是,这将如何失败,我仍然无法理解回调.在JavaScript中,我们可以使用函数回调,但如果有人可以解释,相同的概念如何应用于Java.
我正在尝试使用 Java 11 为单元测试用例运行 powermock + mockito。我正在使用以下版本:
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.28.2'
testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.2'
testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.2'
Run Code Online (Sandbox Code Playgroud)
经过大量反复试验后,我开始使用 Java 11 执行测试,但无法运行具有 Java 11 http 客户端静态块的测试。我添加了
@PowerMockIgnore({"javax.management.*", "sun.security.ssl.*", "javax.net.ssl.*", "java.net.http.*", "jdk.internal.net.http.*"})
Run Code Online (Sandbox Code Playgroud)
但仍然无法让它工作。例外是
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make public java.net.http.HttpClient$Builder jdk.internal.net.http.HttpClientBuilderImpl.priority(int) accessible: module java.net.http does not "exports jdk.internal.net.http" to unnamed module @548b7f67
Run Code Online (Sandbox Code Playgroud)
这是完整的堆栈跟踪:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal …Run Code Online (Sandbox Code Playgroud) 我只是好奇线程 T1 是否有可能部分执行同步块,然后释放对象上的锁,而另一个线程 T2 执行同一块?像这样的东西:
line1: synchronized(this){
line2: if(INSTANCE == null)
line3: INSTANCE = new Object(); //say a variable is initialized
line4: return INSTANCE;
line5: }
Run Code Online (Sandbox Code Playgroud)
线程 T1 是否有可能获取当前对象 ( this) 的锁并执行 line1 和 line2。然后线程 T1 被线程 T2 抢占,T1 释放锁,T2 获取锁this并执行同一块(所有行 1 到 5)。然后线程T1再次获得锁并继续从第3行开始执行?
基本上,T1 将被视为INSTANCEnull,T2 也将被视为 null,并且每个对象都会创建一个新对象。
如果这是不可能的,有人可以解释为什么不可以吗?
附录:
谢谢大家的回答。我的问题有点误导。我到底想问的是,一旦一个线程执行同步块,它是否可以在整个块执行之前释放锁(不是通过显式调用,wait()而是依赖于进程、CPU)?JLS 或 JVM 中是否有约定保证一旦线程开始执行同步块,对象上的锁直到块结束才被释放?我的理解是同步保证没有2个线程可以同时执行该块(或其他同步方法/块),但锁会一直保持到到达块末尾?这很明显,但是 JLS 中有指定吗?
java ×3
callback ×1
coding-style ×1
junit ×1
junit4 ×1
powermock ×1
powermockito ×1
wrapper ×1