什么时候使用'new'关键字?

时间:2012-01-06 22:33:00

标签: java object new-operator

何时需要在Java中使用new关键字。我知道你应该在创建像这样的对象的实例时使用它:

TextView textView = new TextView(this);

有时在代码中我注意到new没有被使用,我感到困惑。 在这行代码中:

    AssetManager assetManager = getAssets();

为什么不像这样创建AssetManager的实例:

AssetManager assetManager = new AssetManager();

然后将其设置为等于getAssests()?

什么时候应该使用new

谢谢!

8 个答案:

答案 0 :(得分:11)

首次显式创建对象时,使用new关键字。然后不需要使用getter方法new获取对象,因为该对象已经存在于内存中,因此不需要重新创建。

如果您想要更详细地了解新访问the oracle docs

如果一个对象为null,那么该对象将需要'new'关键字(这对于未初始化是很奇特的。)

编辑:

在当前情况下,这将始终打印“需要新的”。

Object mObj = null;
if (mObj == null)
    System.out.println("needs new");
else
    System.out.println("does NOT need new");

OUTPUTS: needs new

所以要修复它,你会做类似的事情:

Object mObj = new Object();
if (mObj == null)
    System.out.println("needs new");
else
    System.out.println("does NOT need new");
OUTPUTS: does NOT need new

在这种情况下,我们总会看到“不需要新东西”

答案 1 :(得分:6)

在java中,你总是必须使用new来实例化对象(好吧,几乎总是)。使用getAssests(),您可以检索已创建的一个。我想你的问题来自c ++,其中new分配动态内存,但由于java只有动态对象,所以总是需要new。

答案 2 :(得分:5)

在Java中,new MyClass()的{​​{1}} creates a new instance并返回对它的引用。

同时,声明:

MyClass

定义了一个变量MyClass foo; ,它可以存储对foo实例的引用,或者特殊值MyClass,表示缺少这样的引用。如果您不引用null的任何引用,则其默认值为foo

你当然可以结合这些东西,例如:像这样:

null

或等同地,像这样:

MyClass foo;           // define a variable foo that can store an object reference
foo = new MyClass();   // create a new object and assign a reference to it to foo

但是,每次为引用变量赋值时, 来创建新实例。你也可以这样做,例如这样:

MyClass foo = new MyClass();  // combined variable definition and assignment

甚至:

MyClass foo, bar;      // define two reference variables, foo and bar
foo = new MyClass();   // create a new object and assign a reference to it to foo
bar = foo;             // now foo and bar point to the same object

请注意,在Java中,与C ++等其他语言相反,您永远不能将实际对象(的副本)分配给变量。相反,始终通过对它们的引用来访问Java对象。当有人在Java中谈到“将对象分配给变量”或“将对象作为参数传递”或“从方法中返回对象”时,他们实际上意味着分配或传递或返回引用< / em>到一个对象。

您的代码调用的方法(通常也可以)返回对对象的引用。例如,如果您的类有这样的方法:

MyClass foo = new MyClass(), bar = foo;  // same, but shorter

你可以调用它并保存它返回的引用,如下所示:

private MyClass getSomeObject() {
    // ...some code here...
}

或者像这样:

MyClass foo;
foo = getSomeObject();

我们可以从方法声明中看出MyClass foo = getSomeObject(); 将始终返回对getSomeObject()实例(或MyClass)的引用,但不会返回该实例实际来自的位置。这完全取决于null方法中的代码。代码可能总是在每次调用时创建一个getSomeObject()实例MyClass,并返回对它的引用,或者它可能总是返回对相同对象的引用。或者,当然,它有时会返回对新对象的引用,有时也会返回先前创建的对象。

请注意,如果为变量分配新值,则忘记之前包含的变量。如果忘记的值恰好是对某个对象的最后一个引用,那么该对象本身将被Java的垃圾收集器破坏。

所以,例如,虽然它确实可能做这样的事情:

new MyClass()

通常没有任何意义,因为您要创建一个新的MyClass foo = new MyClass(); // create a new object and assign (a reference to) it to foo foo = getSomeObject(); // forget the previous content of foo and replace it with whatever getSomeObject() returns 实例,只是为了立即丢弃您对它的唯一引用并将其替换为其他内容。实际上,上面的代码完全等同于:

MyClass

唯一可以远程理解的时间是,如果你想要创建一个新的new MyClass(); // create a new object and throw away(!) the reference to it MyClass foo = getSomeObject(); // assign whatever getSomeObject() returns to foo 实例并立即让它被垃圾收集,例如因为MyClass构造函数有一些你想要触发的副作用。但是,由于构造函数通常认为它具有任何非平凡的副作用(或者更常见的是,除了设置新对象之外还要执行任何操作),因此通常不应该有任何编写此类代码的借口。

答案 3 :(得分:3)

当您调用函数的构造函数时,将使用new。 getAssets()返回一个AssetManager,它不需要创建一个新的。

答案 4 :(得分:3)

new始终用于创建新对象。

AssetManager assetManager = getAssets();

只是分配从方法getAssets()返回的值,以引用assetManager

[编辑]

我撒谎new可以这样做:

Foo.class.newInstance();

你也可以使用反射:

Foo.class.getDeclaredConstructors(Class[] parameterTypes).newInstance(arguments);

答案 5 :(得分:2)

使用new为对象分配内存。

使用getXXX()来获取已经分配的现有对象。

答案 6 :(得分:2)

由于你用[android]标记了这一点,我猜你的代码是在ActivityService内。在这种情况下,getAssets()是您要扩展的类的方法。因此,您实际上并没有创建它,而是要求现有代码为您提供已存在的参考。

答案 7 :(得分:0)

注意TextView中的大写字母,以及getAssets中缺少大写字母。 getAssets不是像TextView这样的类,它是一个返回对象的方法。和许多其他人一样,您的资产已经存在。