2012-06-27 3 views
1

Почему некоторые люди делают новую ссылку в методе переменной поля?ссылаясь на переменную класса на локальную переменную

public class Foo { 
    int mFoo[] = {1, 2, 3}; 

    void method() { 
     int foo[] = mFoo; // WHY not just use mFoo? 

     print(foo[0]); // WHY not just use mFoo? 
    } 
} 
+1

Возможно, они думают, что он немного быстрее (что может быть). Или, возможно, чтобы избежать проблем с потоками. – Thilo

+1

@scrappedcola, если я изменю 'foo [0] = 5' то же самое будет отражено и в mFoo. – tomi

+0

@Thilo Threading вопросы? Можете ли вы объяснить, как это помогает? –

ответ

5

Это может быть хорошей идеей, если, например, в другом месте вашего кода, вы измените значение mFoo. Особенно в многопоточном контексте вы хотели бы убедиться, что все еще работаете над нужными данными.

+0

, если бы я изменил 'foo [0] = 5', он также отразится на mFoo. Так вы могли бы объяснить, почему это было бы иначе в многопоточном контексте? – tomi

+0

Представьте, что вы находитесь в многопоточном приложении. В одном из ваших потоков вы начинаете выполнять итерацию на своем столе. В другом потоке вы выполняете 'mFoo = anotherTable;' Что будет дальше в вашем итерационном потоке? –

+0

thx для уточнения. – tomi

1

Это просто не имеет смысла, если вы используете так же, как это:

int[] local = somethingElse; 
... // changes to local will reflect on somethingElse 

Это имело бы смысл, если реальная копия будет сделано, как:

int[] local = Arrays.copyOf(somethingElse,somethingElse.lenght()) 
... // changes to local will not reflect on somethingElse 

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

тест можно сделать с помощью следующего кода:

int[] test = new int[] {1,2,3}; 
int[] test2 = Arrays.copyOf(test,test.length); 
test2[0] = 9; 
System.out.println(Arrays.toString(test)); 
2

Это зависит от вашей цели. Если вы хотите изменить любой объект, переданный в качестве параметра, вы бы не создали новый экземпляр типа объекта, на который ссылается.

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

+0

Однако в вопросе не упоминаются новые экземпляры. – Thilo

3

Это было так (и до сих пор с Java ME AFAIK), который загружает поле в локальную переменную и использует его несколько раз быстрее, чем доступ к полю несколько раз.

Однако сегодня использование локальной переменной может привести к запуску JIT-компилятора и использование локальной переменной таким образом может быть медленнее.

+0

Действительно? Я не могу представить, что это замедляет ситуацию. (Я видел недавние тесты, демонстрирующие ускорения этой методики даже на Java 7-сервере, но только крошечные в чрезвычайно критическом для производительности коде.) –

+0

Это было утверждение одного из разработчиков JVM менее месяца назад. Я думаю, это зависит от ситуации. Я сам этого не видел. ;) –

0

В случае примитивных типов, таких как int, вы копируете значения, а не указатели, поэтому исходный массив по-прежнему не тронут после вызова метода «печать». Она не держать, хотя для массивов

+0

, если у нас есть int массивы, тогда мы также просто указываем и не копируем. это будет копирование: int i = 5; int j = i; – tomi

2

Там в принят ответ уже, но использование имеет смысл в этом контексте:

private Class<?> clazz = ...; 

public void foo() { 
    Class<?> current = clazz; 
    while (current != Object.class) { 
     // do some stuff. 
     current = current.superclass(); 
    } 
} 

В этом примере вы постоянно переназначения «ток» на новое значение. Представьте себе побочный эффект без переменной и, если вы продолжали делать:

clazz = clazz.superclass(); 

Вы бы изменения поля в самом объекте, а не локально на свой метод, поэтому повторные вызовы «Foo» не будет выставлять поведение, которое вы ожидаете.

+0

принятый ответ был первым, который разъяснил мне эту проблему. – tomi

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