Авторские Материалы о событиях в Израиле на Ближнем Востоке и в мире

IsraMir.com - Израильская журналистика

Default color brown color green color red color blue color
Вы сейчас тут: Новости arrow Техотдел arrow Свет ученья arrow Thinking in Java, 2nd edition -5
Skip to content
Thinking in Java, 2nd edition -5 - Оператор принимает... Версия для печати Отправить на e-mail
Содержание
Оператор принимает...
Эффект наложения...
Математические...
Sunday, 30 April 2006 | Bruce Eckel для раздела Ученье – свет
Использование операторов Java
ThinkinginJava,2ndedition-5isramir.comОператор принимает один или больше аргументов и производит новое значение. Аргументы располагаются по-другому, в отличие от обычного вызова метода, но эффект тот же самый. Вы будете чувствовать себя остаточно комфортно с общей концепцией операторов, основываясь на ваш предыдущий опыт программирования. Сложение (+), вычитание и унарный минус (-), умножение (*), деление (/) и присвоение (=) всегда работают так же, как и в других языках программирования.
 
Все операции производят значения из своих операндов. В дополнение, оператор может сменить значение операнда. Это называется побочным действием. Самое общее в использовании операторов, которые модифицируют свои операнды, то, что они генерируют побочное действие, но вы должны держать в уме, что производимое значение доступно для вашего использования только в операторах без побочных действий.
Почти все операторы работают только с примитивными типами. Исключение составляют ‘=’, ‘==’ и ‘!=’, которые работают со всеми объектами (и являются смущающим местом для объектов). Вдобавок, класс String поддерживает ‘+’ и ‘+=’.
 
Предшествование
Предшествующий оператор определяет, как вычисляется выражение, когда имеются несколько операторов. Java имеет специальные правила, которые определяют порядок вычислений. Легче всего запомнить, что умножение и деление вычисляются перед сложением и вычитанием. Программисты часто забывают другие правила предшествования, так что вы должны использовать круглые скобки для явного упорядочивания порядка вычислений.
 
Например:
 
A = X + Y - 2/2 + Z;
 
имеет весьма разную трактовку для того же выражения с круглыми скобками:
 
A = X + (Y - 2)/(2 + Z);
 
Присваивание
Присваивание выполняется с помощью оператора =. Это означает “взять значение правой части (часто называемое rvalue) и скопируй его в левую сторону (часто называемую lvalue). rvalue - это любая константа, переменная или выражение, которое может произвести значение, но lvalue должно быть определенной, поименованной переменной. (То есть, здесь должно быть физическое пространство для хранения значения.) Например, вы можете присвоить постоянное значение переменной (A = 4;), но вы не сможете присвоить ничего постоянному значению — оно не может быть lvalue. (Вы не можете сказать 4 = A;.)
 
Присвоение примитивов достаточно прямое и понятное. Так как примитивы хранят реальное значение, а не ссылку на объект, то когда вы присваиваете примитивы, вы копируете содержимое с одного места в другое. Например, если вы говорите A = B для примитивов, то содержимое B копируется в A. Если вы потом измените A, B не подвергнется изменениям. Как программист, это то, что вы хотите ожидать в большинству случаев.
 
Однако когда вы присваиваете объекты, все меняется. Когда бы вы ни манипулировали объектом, то, чем вы манипулируете - ссылка, так что когда вы присваиваете “один объект другому”, на самом деле вы копируете ссылку из одного места в другое. Это означает, если вы скажете C = D для объектов, в конце вы получаете, что C и D указывают на объект, на который первоначально указывает только D. Приведенный ниже пример будет демонстрировать это.
 
Вот этот пример:
// Присвоение объектов немного хитрая вещь.
 
class Number {
  int i;
}
 
public class Assignment {
  public static void main(String[] args) {
    Number n1 = new Number();
    Number n2 = new Number();
    n1.i = 9;
    n2.i = 47;
    System.out.println("1: n1.i: " + n1.i +
      ", n2.i: " + n2.i);
    n1 = n2;
    System.out.println("2: n1.i: " + n1.i +
      ", n2.i: " + n2.i);
    n1.i = 27;
    System.out.println("3: n1.i: " + n1.i +
      ", n2.i: " + n2.i);
  }
}
 
Класс Number - прост и внутри функции main( ) создаются два его экземпляра .(n1 и n2). Переменная Значения i в каждом из Number имеют разные значения, а затем n2 присваивается n1, а n1 изменяется. Во многих языках программирования вы можете ожидать, что n1 и n2 независимы все время, но потому что вы присвоили ссылку, здесь приводится вывод, который вы увидите:
 
1: n1.i: 9, n2.i: 47
2: n1.i: 47, n2.i: 47
3: n1.i: 27, n2.i: 27
 
Изменение объекта n1 проявляется в изменении объекта n2! Это потому, что и n1 и n2 содержат одну и ту же ссылку, которые указывают на один и тот же объект. (Начальная ссылка, которая была в n1 и указывала на объект, содержащий значение 9 была переписана во время присвоения и на самом деле потерялась; ее объект будет очищен сборщиком мусора.)
 
Этот феномен часто называется эффектом наложения (aliasing) и это фундаментальный путь, которым работают в Java с объектами. Но что, если вы не хотите, чтобы в этом случае возник эффект наложения? Вы можете воздержаться от присвоения и сказать:
n1.i = n2.i;
 
При этом сохраняются два различных объекта вместо отбрасывания одного и прикрепления n1 и n2 к одному и тому же объекту, но вы скоро поймете, что манипулирование полями внутри объекта - грязный метод и идет в разрез с принципами хорошего объектно-ориентированного дизайна. Это не тривиальная тема, так что оставим ее для приложения A, которое посвящено эффекту наложения. Тем временем, вы должны отложить в мозгу, что присвоение для объектов может стать источником сюрпризов.
 


 

Добавить комментарий

:D:lol::-);-)8):-|:-*:oops::sad::cry::o:-?:-x:eek::zzz:P:roll::sigh:


Автотранслитерация: выключена

Защитный код

Powered by jComments