使用"new"关键字创建的Java对象和不使用"new"创建的对象有什么区别?

4
创建对象时,使用 "new" 和不使用 "new" 有什么区别?
例子:
Thing someThing = new Thing();

对比。

Path filePath = Path.get("C:\\......)

在第一个示例中,我理解在实例化对象时,“new”会为“someThing”对象分配内存,并且该内存位置由“someThing”引用。
我的教科书上说使用第二个示例来“创建Path对象”。区别只在于对象的存储方式或内存分配吗?我不确定为什么要以这种方式创建对象。

你尝试过查看这里询问的路径源代码吗? - Danubian Sailor
7个回答

12
在第二种情况下,您正在使用一个静态方法,该方法内部创建对象或传递对现有对象的引用。这是一种常见的模式,特别是当API希望隐藏内部实现时(正如在这里所示)。

4
要明确的是,Path.get 方法几乎肯定在其实现中某个地方调用了 new - Louis Wasserman
1
静态方法不一定会创建对象,它可能被存储,而你只是检索其引用。但在所提供的示例中并非如此。 - DSquare
@DSquare,没错。我更新了答案以包含那个细节。谢谢! - Martin Serrano

6

没有区别。第二个例子是一个工厂方法。

您需要传入一些参数,该方法将在Path的实际实例类上某个时刻调用new


4

虽然静态工厂方法的行为类似于构造函数,但也存在一些区别需要指出:静态工厂方法不必返回当前类型,而可以返回一个子类型,而构造函数则创建当前类的实例。(假想的)示例:

public static Path create(String name) {
    return new AbsolutePath(name); // subclass/implementation of Path
}

从实现角度来看,这可以为您提供后续扩展的很大灵活性。例如,您可以实现一些逻辑,该逻辑会在方法内决定要创建哪种具体类型。您可以缓存实例并返回它们。您可以每次返回相同的实例(单例)。等等。

另一个方面:您实际上可以为静态工厂方法命名,以便代码更易于阅读:

public static Path createAbsolute(String name) { ... }
public static Path createRelative(String name) { ... }

2
第一种选择可以确保创建了一个新的对象(或多或少地,java.lang.* 类有点特殊)。接下来考虑第二个选项:
Path filePath = Path.get("C:\\......)

没有任何保证你存储在filePath中的实例是Path类的实例,它可能是Path类的子类的实例。类似的情况也发生在Calendar类上:Calendar是一个抽象类,因此

Calendar c=Calendar.getInstance();

变量 c 实际上是一个 GregorianCalendar

另一个区别:

class Singleton {

    private Singleton s=null;

    private Singleton(){};

    public static Singleton getSingleton() {
        if (s==null) {
            s=new Singleton();
        }
        return s;
    }
}

无论您调用多少次 getSingleton,您只会创建一个对象。

1
当你使用new关键字时,会创建一个特定类的对象。
这里Thing someThing = new Thing();中,somethingThing类的对象。
Path filePath = Path.get("C:\......)

Path 是一个类,拥有静态方法 get(),它接受字符串参数并返回类似于 Path 的东西。

public static Path get(String arg)
{
return path;
}

0

内存是通过第二个实例中的Path.get方法调用分配的。这允许库通过其自己的初始化例程为Path变量进行处理,可能执行其他检查。New只分配内存。内存也可以按某种结构进行排序和存储,以便通过缓存不会不断重新加载相同的对象。就我个人而言,我总是调用工厂方法而不是自己创建一个对象,但是这可能被认为是一种风格,因为几乎可以通过构造函数实现使用工厂方法完成的所有操作。


0
在你的例子中,你假设一个对象是没有使用"new"创建的。这是一个错误的假设。第二个例子中也是使用了"new"来创建对象。
仅仅因为你看不到"new"并不意味着它在函数中没有被调用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接