没有类型不匹配 - 从原始int转换为布尔值

时间:2016-10-04 07:14:09

标签: java decompiling

考虑来自 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     }

完全符合预期。

3 个答案:

答案 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)。