Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将类变量引用到局部变量_Java - Fatal编程技术网

Java 将类变量引用到局部变量

Java 将类变量引用到局部变量,java,Java,为什么有些人在方法中对字段变量进行新的引用 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? } } 如果你像这样使用,那就没有意义了: int[] local = somethingElse; ..

为什么有些人在方法中对字段变量进行新的引用

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?
    }
}

如果你像这样使用,那就没有意义了:

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));

如果你像这样使用,那就没有意义了:

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));

例如,如果在代码的另一个位置更改mFoo的值,这可能是一个好主意。特别是在多线程环境中,您需要确保仍在处理正确的数据。

例如,如果在代码的另一个位置更改mFoo的值,这可能是一个好主意。特别是在多线程环境中,您需要确保仍在处理正确的数据。

这取决于您的目标。如果要修改作为参数传入的任何对象,则不会创建引用对象类型的新实例


否则,您将创建一个新实例,您可以自由修改该实例,而无需担心对传入对象的修改。这通常用于多线程应用程序

这取决于你的目标。如果要修改作为参数传入的任何对象,则不会创建引用对象类型的新实例

否则,您将创建一个新实例,您可以自由修改该实例,而无需担心对传入对象的修改。这通常用于多线程应用程序

过去的情况是(Java ME AFAIK仍然如此),将字段加载到局部变量并多次使用它比多次访问字段要快

然而,今天,以这种方式使用局部变量可能会混淆JIT编译器,并且以这种方式使用局部变量可能会更慢。

过去的情况是(Java ME AFAIK仍然如此),将字段加载到局部变量中并多次使用它比多次访问字段更快


然而,现在这种使用局部变量的方式可能会混淆JIT编译器,并且这种使用局部变量的方式可能会更慢。

对于像int这样的基元类型,您处理的是值,而不是指针,因此在调用方法“print”后,您的原始数组仍然保持不变。但对于数组来说,它不适用于在int等基元类型的情况下,您处理的是值,而不是指针,因此在调用方法“print”后,原始数组仍然保持不变。不过,对于数组来说,它并不成立,已经有了一个公认的答案,但在这种情况下,使用它更有意义:

private Class<?> clazz = ...;

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

您将更改对象本身中的字段,而不是本地更改方法,因此对“foo”的重复调用不会显示您期望的行为。

已经有了一个公认的答案,但在这种情况下使用它更有意义:

private Class<?> clazz = ...;

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


您将更改对象本身中的字段,而不是本地更改方法,因此对“foo”的重复调用不会显示您期望的行为。

可能他们认为它稍微快一点(可能是这样)。或者可能是为了避免线程问题。@scrapedcola如果我更改'foo[0]=5',同样也会反映到mFoo。@Thilo线程问题?你能详细说明这有什么帮助吗?@EricB。看到被接受的答案,也许他们认为它稍微快一点(可能是这样)。或者可能是为了避免线程问题。@scrapedcola如果我更改'foo[0]=5',同样也会反映到mFoo。@Thilo线程问题?你能详细说明这有什么帮助吗?@EricB。看到公认的答案了吗?真的吗?我无法想象这会让事情变慢。(我看到最近的基准测试甚至在Java7-server上展示了这种技术的加速效果,但在性能极其关键的代码中只有很小的加速效果。)这是一位JVM开发人员在不到一个月前提出的观点。我想这要视情况而定。我自己也没见过真正地我无法想象这会让事情变慢。(我看到最近的基准测试甚至在Java7-server上展示了这种技术的加速效果,但在性能极其关键的代码中只有很小的加速效果。)这是一位JVM开发人员在不到一个月前提出的观点。我想这要视情况而定。我自己也没见过但是,问题中没有提到创建新实例。但是,问题中没有提到创建新实例。如果我将'foo[0]=5'更改为'foo[0]=5',它也将反映在mFoo上。那么,你能详细解释一下为什么在多线程环境中这会有所不同吗?假设你在一个多线程应用程序中。在一个线程中,您开始在表上迭代。在另一个线程中,执行
mFoo=anotherTable迭代线程中接下来会发生什么?如果我更改'foo[0]=5',它也会反映在mFoo上。那么,你能详细解释一下为什么在多线程环境中这会有所不同吗?假设你在一个多线程应用程序中。在一个线程中,您开始在表上迭代。在另一个线程中,执行
mFoo=anotherTable迭代线程中接下来会发生什么?如果我们有int数组,那么我们也只是指向而不是复制。这将是复制:int