Что происходит с программой, когда при присвоении значения переменной используется сразу несколько методов?
Есть строки кода (никак не связанные между собой):
mCrime = CrimeLab.get(getActivity()).getCrime(crimeId);
UUID crimeId = (UUID) getIntent().getSerializableExtra(EXTRA_CRIME_ID);
fm.beginTransaction().add(R.id.fragment_container, fragment).commit();
Насколько я понимаю, данные строки являются компактным вариантом присвоения значения переменной. Но, мне не всегда понятно, что именно происходит в коде, при таких записях, почему методы вызываются именно в этой последовательности. И, главное, как бы это было записано в некомпактном виде?
Ответы (1 шт):
Первые две строки действительно выполняют присвоение (хотя я не очень понял, почему Вы назвали его компактным).
В третьей строке нет присвоения.
Подробнее:
mCrime = CrimeLab.get(getActivity()).getCrime(crimeId);
Можно развернуть, как:
Activity activity = getActivity();
CrimeLab crimeLab = CrimeLab.get(activity);
mCrime = crimeLab.getCrime(crimeId);
То есть сначала на основе Activity конструируется объект класса CrimeLab, затем из этого объекта получается объект класса Crime через метод getCrime, который уже в свою очередь присваивается в переменную mCrime.
Теперь вторая из Ваших строк:
UUID crimeId = (UUID) getIntent().getSerializableExtra(EXTRA_CRIME_ID);
Её можно разбить так:
Intent i = getIntent(); //получаем интент
Object id = i.getSerializableExtra(EXTRA_CRIME_ID); //получаем id без указания типа
UUID crimeId = (UUID) id; //приводим тип и сохраняем в crimeId
То есть и в первой и во второй строке действительно происходит присвоение, но, так как Вам нужен только конечный объект и не нужны промежуточные, то им (промежуточным объектам) не задаются имена, они нигде не сохраняются.
Во второй строке присвоения нет.
fm.beginTransaction().add(R.id.fragment_container, fragment).commit();
Так же детальный разбор:
FragmentTransaction transaction = fm.beginTransaction(); //создать транзакцию
transaction.add(R.id.fragment_container, fragment); //добавить действие в транзакцию
transaction.commit(); //запустить транзакцию
Если переписать Вашу третью строку так, как я сделал выше, то присвоение действительно будет (и оно будет в bytecode). Однако, Вам нет необходимости хранить объект транзакции, Вам нужно создать её и сразу запустить.
Методы, очевидно, вызываются в порядке слева-направо и сверху-вниз. То есть Вашу третью строку, например, можно переписать ещё и так:
fm
.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
Форма записи в кратком виде является более удобной и короткой, потому (обычно) используют именно ее. При создании bytecode всё будет выглядеть так же, как если бы Вы написали все присвоения.
И ещё по поводу порядка вызовов методов! Из правила слева-направо, сверху-вниз есть небольшое исключение:
mCrime = CrimeLab.get(getActivity()).getCrime(crimeId);
Конкретно здесь сначала будет вызван метод getActivity, а уже потом CrimeLab.get. В действительности перед вызовом метода проверяются его параметры. Если среди них есть метод (1) (вместо переменной), то сначала вызовутся все методы для получения параметров, а уже потом сам метод (1)