2017-01-17 14 views
6

Я имею путаницу в вызове метода нестатическаяВызывающие методы на ссылочной переменной против Вызов методов на новый объект

class A { 
    void doThis() {} 

    public static void main(String... arg) { 
     A a1 = new A(); 
     a1.doThis();  // method - 1 
     new A().doThis(); // method - 2 
    } 
} 

Я знаю, что оба метод-1 и метод-2 будет звонить doThis(), но есть ли какие-либо функциональные различия? Какова будет ссылка на новый объект в method-2.

+1

В этом конкретном случае нет, они имеют точно такой же эффект. – BackSlash

+0

определенно да? потому что 'new A()' создает новый 'A' (потому что' new A() 'и' a' являются ** не ** одним и тем же объектом) – Moira

+2

Есть разница, если вам нужно сделать что-то еще с новым объектом потом, конечно. Я не уверен, что вы спрашиваете: «Какая будет ссылка на новый объект в методе-2». хотя - это ссылка на вновь созданный объект ... –

ответ

2

Есть ли какие-либо функциональные различия?

Оба будут вести себя одинаково.

Второй вариант не позволяет повторно использовать этот экземпляр. Это может быть удобным и лаконичным в возвращаемом значении однострочного (например, рассмотрим шаблон строителя, где каждый метод построения возвращает половину инициализировано экземпляр):

return new Builder().a().b().build(); 

или если объект был создан только для выполнения определенного действие один раз.

Какая ссылка на новый объект в методе-2?

Он больше не существует (более точно, мы не имеем доступа к нему), если doThis возвращает this, которые вы могли бы быть в состоянии поставить в переменной после выполнения метода.

Могу ли я сказать, что метод-2 является неправильным способом вызова нестатического метода?

Нет. Почему мы должны создавать переменную, если эта переменная никогда не будет использоваться впоследствии?

+0

поэтому в методе-2 * * new A() ** - это экземпляр, а также переменная? –

+0

@ArunSudhakaran, 'new A()' - это экземпляр, но не переменная (которая относится только к месту, где располагается экземпляр) – Andrew

+0

Но объект без ссылочной переменной является заброшенным объектом. Так компилятор добавляет дополнительный код в .class файл для метода-2, потому что в классе ** new A() ** нет никакой ссылочной переменной? –

2

Давайте посмотрим, что говорит код в простом английском языке:

 A a1 = new A(); 
     a1.doThis(); 
  1. Создать новый экземпляр А.
  2. хранить ссылку на него в переменной a1.
  3. Звоните doThis() на наш заказ.

В то время как new A().doThis(); гласит:

  1. Создать новый экземпляр А.
  2. Вызов doThis() на нашем примере.

Таким образом, единственное различие заключается в том, сохраняете ли вы его в локальной переменной или нет. Если вы больше не используете значение в переменной, то это различие не имеет значения. Но если вы хотите вызвать другой метод на том же объекте, скажем, a1.doThat(), тогда у вас проблемы со вторым решением, так как у вас больше нет ссылки на исходный экземпляр.

Зачем вам нужен этот же объект? Поскольку методы могут изменять внутреннее состояние объекта, это в значительной степени то, о чем идет речь.

2

Позволяет взглянуть на оба этих метода один за другим.

Метод-1

A a1 = new A(); 
a1.doThis(); 

В метод-1, у вас есть ссылка на созданный экземпляр A, т.е. a1, и вы можете назвать как многие методы этого экземпляра из A с помощью этого ссылка a1. В основном вы можете повторно использовать этот конкретный экземпляр A, используя его ссылку a1.

Метод-2

new A().doThis(); 

Однако в метод-2, у вас нет какой-либо переменной, которая хранит ссылку на вновь созданный экземпляр A. Как вы будете ссылаться на этот конкретный экземпляр A, если вам нужно вызвать любой другой метод для этого конкретного экземпляра A? Вы не сможете повторно использовать этот экземпляр A, если вы создадите экземпляр с использованием метода-2, и вы потеряете этот экземпляр, как только он будет использован.

4

Не будет никакой разницы в выполнении этих методов, но в случае new A().doThis() вы потеряете ссылку на экземпляр объекта, на который вы вызвали метод, и вы не сможете используйте его далее в своем коде. Все изменения, которые этот метод мог сделать для внутреннего состояния экземпляра, будут потеряны.

В случае A a1 = new A(); a1.doThis(); вы сохраните экземпляр объекта (в переменной a1) и возможные изменения, внесенные в его состояние, выполненные по методу doThis(). Затем вы сможете продолжить работу с этим объектом.