2013-03-08 4 views
57
public void increment(){ 
    int zero = 0; 

    int oneA = zero++; // Compiles 

    int oneB = 0++; // Doesn't compile 

    int oneC = getInt()++; // Doesn't compile 
} 

private int getInt(){ 
    return 0; 
} 

Они все int, почему бы не B & C компилировать? Это связано с тем, что оператор ++ отличается от = 0 + 1;?Почему оператор post increment не работает над методом, который возвращает int?

Invalid argument to operation ++/--

+38

Замечание: судя по тому, как вы назвали свои переменные, вы, кажется, предполагаете, что 'int oneA = zero ++; 'присваивает * one *' oneA'. Это неверно. Оператор * post * increment возвращает значение * old * (non-incremented). После 'int oneA = zero ++;', 'oneA' -' 0', а 'zero' -' 1'. – Heinzi

+0

@Heinzi true! Я заметил это в своем реальном коде, это был всего лишь пример – Blundell

+2

Итак, в вашем коде вы бы не просто автоматически записывали 'int oneC = getInt() + 1;'? –

ответ

143

i++ - это назначение переменной i.

В вашем случае zero++ является эквивалентом zero = zero + 1. Таким образом, 0++ будет означать 0 = 0 + 1, что не имеет смысла, а также getInt() = getInt() + 1.

Более точно:

int oneA = zero++; 

означает

int oneA = zero; 
zero = zero + 1; // OK, oneA == 0, zero == 1 

int oneB = 0++; 

означает

int oneB = 0; 
0 = 0 + 1; // wrong, can't assign value to a value. 

int oneC = getInt()++; 

означает

int oneC = getInt(); 
getInt() = getInt() + 1; // wrong, can't assign value to a method return value. 

С более общей точки зрения, переменным является L-значением, а это означает, что она относится к ячейке памяти, и, следовательно, может быть назначен. л в L -value обозначает оставил стороны оператора присваивания (т.е. =), даже если L-значения могут быть найдены либо на левой стороне или на правой стороне оператора присваивания (x = y), например, ,

Противоположное R-значение (R обозначает правой стороны оператора присваивания). R-значения могут использоваться только с правой стороны операторов присваивания, чтобы присвоить что-то значение L. Как правило, значения R - это литералы (числа, строки символов ...) и методы.

+0

Ах конечно Duh, потому что он выполняет задание, тогда B & C не имеет смысла да! – Blundell

+1

+1, я просто хочу добавить небольшой комментарий об этом ответе, «i» - это выделение памяти, которое имеет значение и имеет адрес, поэтому i ++ означает, что 1-идти по адресу в памяти. 2- получить значение в этом address 3-increment it 4-reallocate значение снова в этом адресе 'i = i + 1', поэтому, когда мы не инициализируем переменную типа: int x, то x ++; мы получаем ошибку, потому что в этом адресе нет значения, в случае 0 ++, да, это не имеет смысла, потому что 0 - это просто значение –

+2

Фактически, i = i + 1, похоже, эквивалентен ++ i, а не i ++ , (На самом деле я был немного шокирован, увидев, что присвоения приводят к значениям в Java) –

5

Оба B и C делают компилятор говорит:

unexpected type, required: variable, found: value

Таким образом, вы не можете увеличивать значение, только переменную.

29

Потому что, как указано в JLS:

The result of the postfix expression must be a variable of a type that is convertible (§5.1.8) to a numeric type, or a compile-time error occurs.

14

getInt() не int

getInt() возвращает int

++ оператор делает две вещи increment + assignment

Так Ф.О. r ++ Оператор для работы вам нужна переменная, чтобы сохранить результат операции инкремента, который 0 и getInt() оба нет.

2

Потому что 0 является rValue (то есть вы можете использовать его только справа от оператора присваивания) not a lValue.

++ оператор увеличивает значение и устанавливает его себе, поэтому 0++ предоставит вам сообщение об ошибке.

4

Why doesn't the post increment operator work on a method that returns an int?

Потому что это метод геттера, и нет смысла изменять значение через геттер.


int z = x + y++; 

эквивалентно:

int z = x + y; 
y = y + 1; 

так что это не действует, чтобы иметь что-то вроде:

int z = x + getY()++; 

что эквивалентно:

int z = x + getY(); 
getY() = getY() + 1; // invalid! 
+0

, так что если метод был вызван setInt, будет ли он работать, чтобы увеличить его? –

+0

@HussainAkhtarWahid, конечно, нет, я имею в виду, когда вы хотите изменить какую-то переменную, вы можете сделать это с помощью сеттера, а не получателя. Напомнил мой ответ. –

+0

++ для этого 'getY() = getY() + 1; // invalid! ' –

3

0++

Это эквивалентно 0 = 0 + 1; и, конечно же, невозможно.

т. Е. Он должен быть l-value, чтобы назначить ему.

getInt()++;

Аналогичная причина здесь.

+0

+ хороший ответ, что насчет' ++ (i | i) '? потому что 'i | i' always 'i' также' i & i' == 'i' –

10

Операции до и после работы работают только с переменными или lvalues ​​по мере их вызова. lvalue является коротким для левого значения, то есть что-то, что может стоять слева в задании. В вашем примере:

zero = 1; // OK 
    0 = 1; // Meaningless 
    getInt() = 1; // Also meaningless 

// Ю.К.

0

postincrement и прединкремент могут применяться только с помощью variable.So первого случая компиляции.

0

Ответьте на свой вопрос «из коробки».

Когда я сомневаюсь в использовании оператора, я думаю, «что его перегруженная функция эквивалентна» этого оператора?

Я знаю, что Java-операторы не имеют перегрузки оператора, это просто альтернативный способ сделать решение.

В этом случае:

... 
x++; 
... 

следует читать как:

... 

int /* function */ postincrement (/* ref */ int avalue) 
{ 
    int Result = avalue; 

    // reference value, 
    avalue = avalue + 1; 

    return Result; 
} 

... 
postincrement(/* ref */ x); 
... 

И:

... 
++x; 
... 

... 

int /* function */ preincrement (/* ref */ int avalue) 
{ 
    // reference value, 
    avalue = avalue + 1; 

    int Result = avalue; 

    return Result; 
} 

... 
preincrement(/* ref */ x); 
... 

Таким образом, оба варианта "++", работа в качестве функция, которая получает переменный параметр по ссылке.

Итак, буквальное значение типа «0 ++» или результат функции, такой как «getInt() ++», не являются ссылками на переменные.

Cheers.

0

Поскольку функция return - это выражение RHS, а операции с приращением/уменьшением до/после операции могут применяться только к выражениям LHS.