2016-10-04 2 views
1

Рассмотрите фрагмент из CopyOnWriteArrayList.Нет несоответствия типа - преобразование из примитивного int в boolean

Тип возврата метода является примитивным булево тогда примитивным INT возвращается. Декомпилятор используется

IS-

/* Eclipse, класс Decompiler плагин, авторские права (с) 2016 Чэнь Чао ([email protected]) */

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(); 
    } 
} 

ли decompiler Исход ошибки, так как код в выбранных строках невозможно компилировать или есть какая-то другая причина для этого?

Если вы посмотрите на код 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  } 

, который отлично в соответствии с ожидаемым.

+8

Пожалуйста, отправьте код как текст, а не изображения. Вы тратите мою мобильную пропускную способность. –

+3

И вы не получите помощь от людей в корпоративных сетях, которые блокируют imgur.com – Aaron

+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(); 
    } 
} 
2

Java не имеет никаких инструкций по обращению с булевыми (для доступа булевых массивов, за исключением), они реализуются в виде целых чисел со значениями 0 и 1.

boolean a = true; 
boolean b = false; 

компилируется в

iconst_1 
istore_1 
iconst_0 
istore_2 

Этот дизассемблер просто смутился этим.
На самом деле все интегральные примитивные типы, меньшие, чем int, хранятся как int (это не проблема, так как Java в любом случае расширяет мелкие интегральные типы до int).

3

От Java Virtual Machine Specification, section 2.3.4:

Хотя виртуальная машина Java определяет логический тип, он обеспечивает только очень ограниченную поддержку. Нет инструкций Java Virtual Machine, предназначенных исключительно для операций над булевыми значениями. Вместо этого выражения на языке программирования Java, которые работают с булевыми значениями, скомпилированы для использования значений типа данных виртуальной машины Java.

Таким образом, декомпилятор технически корректен, что возвращаемая переменная является int, по крайней мере, на уровне байт-кода.

Существует одно исключение: логические массивы не эквивалентны Int массивов:

Виртуальная машина Java имеет прямую поддержку логических массивов. [...] В реализации Oracle Java Virtual Machine логические массивы на языке программирования Java кодируются как массивы байтов виртуальной машины Java, используя 8 бит на каждый элемент в буфере.

Смежные вопросы