我不确定,但我很确定我在Oracle Java实现中发现了一个错误(或一个未记录的功能)(1.7.0_67和1.8.0_31我可以验证为受影响).
症状
当管道已满时,对管道的写入可能会比管道再次释放所需的时间长一秒.问题的一个最小示例如下(我已将此处显示的示例推送到GitHub上的存储库):
private static void threadA() throws IOException, InterruptedException {
logA("Filling pipe...");
pos.write(new byte[5]);
logA("Pipe full. Writing one more byte...");
pos.write(0);
logA("Done.");
}
private static void threadB() throws IOException, InterruptedException {
logB("Sleeping a bit...");
Thread.sleep(100);
logB("Making space in pipe...");
pis.read();
logB("Done.");
}
Run Code Online (Sandbox Code Playgroud)
pis并pos分别连接PipedInputStream和PipedOutputStream实例.logA并且logB是输出线程名称(A或B)的辅助函数,以毫秒为单位的时间戳和消息.输出如下:
0 A: Filling pipe...
6 B: Sleeping a bit...
7 A: Pipe full. Writing one more byte...
108 B: Making space in …Run Code Online (Sandbox Code Playgroud) 我创建了一个MWE,通过添加<?>解决编译器错误来更改单行.
以下代码无法编译:
import java.util.List;
public class MainClass {
public void traverse() {
List<MyEntity> list = null /* ... */;
for (MyEntity myEntity : list) {
for (String label : myEntity.getLabels()) { // <-- Offending Line
/* ... */
}
}
}
interface MyEntity<T> {
T get();
List<String> getLabels();
}
}
Run Code Online (Sandbox Code Playgroud)
编译器错误是:
Error:(9, 51) java: incompatible types: java.lang.Object cannot be converted to java.lang.String
Run Code Online (Sandbox Code Playgroud)
更改违规行中的定义MyEntity myEntity以MyEntity<?> myEntity解决问题.我想知道为什么这个for-each的返回类型被视为an Object而不是a String,除非我将通配符添加到父类?请注意,getLabels()它本身不包含泛型.
根据第14.14.2章.在Java语言规范中,使用迭代器将for-each编译为循环.有趣的是,扩大的for-each于这样的迭代器手动 …