考虑来自 CopyOnWriteArrayList 的代码段。
方法的返回类型是原始布尔,而原始int 正在返回。使用的反编译器是 -
/ * Eclipse Class Decompiler插件,版权所有(c)2016陈超 (cnfree2000@hotmail.com)* /
public boolean add(E paramE) {
ReentrantLock localReentrantLock = this.lock;
localReentrantLock.lock();
try {
Object[] arrayOfObject1 = getArray();
int i = arrayOfObject1.length;
Object[] arrayOfObject2 = Arrays.copyOf(arrayOfObject1, i + 1);
arrayOfObject2[i] = paramE;
setArray(arrayOfObject2);
int j = 1;
return j; // ?????????
} finally {
localReentrantLock.unlock();
}
}
反编译器是否是错误的来源,因为所选行中的代码无法编译,或者是否还有其他原因?
如果查看代码here,则行为 -
414 public boolean More ...add(E e) {
415 final ReentrantLock lock = this.lock;
416 lock.lock();
417 try {
418 Object[] elements = getArray();
419 int len = elements.length;
420 Object[] newElements = Arrays.copyOf(elements, len + 1);
421 newElements[len] = e;
422 setArray(newElements);
423 return true;
424 } finally {
425 lock.unlock();
426 }
427 }
完全符合预期。
答案 0 :(得分:3)
它看起来像是。以下是使用Java Decompiler(JRE 1.8.0_60)反编译的以下代码。
public boolean add(E paramE)
{
ReentrantLock localReentrantLock = this.lock;
localReentrantLock.lock();
try
{
Object[] arrayOfObject1 = getArray();
int i = arrayOfObject1.length;
Object[] arrayOfObject2 = Arrays.copyOf(arrayOfObject1, i + 1);
arrayOfObject2[i] = paramE;
setArray(arrayOfObject2);
return true;
}
finally
{
localReentrantLock.unlock();
}
}
答案 1 :(得分:3)
来自Java Virtual Machine Specification, section 2.3.4:
虽然Java虚拟机定义了一个布尔类型,但它只提供非常有限的支持。没有Java虚拟机指令专门用于对布尔值的操作。相反,Java编程语言中对布尔值进行操作的表达式将被编译为使用Java虚拟机int数据类型的值。
因此,反编译器在技术上是正确的,返回的变量是一个int,至少在字节码级别。
有一个例外:布尔数组不等于int数组:
Java虚拟机直接支持布尔数组。 [...]在Oracle的Java虚拟机实现中,Java编程语言中的布尔数组被编码为Java虚拟机字节数组,每个布尔元素使用8位。
答案 2 :(得分:2)
Java没有处理布尔值的指令(访问布尔数组除外),它们实现为值为0和1的整数。
boolean a = true;
boolean b = false;
编译成
iconst_1
istore_1
iconst_0
istore_2
反汇编者对此感到困惑 事实上,所有小于int的整数基本类型都存储为int(这不是一个问题,因为Java无论如何都会将较小的整数类型扩展为int)。