为什么有些Java库使用静态newInstance函数而不是构造函数?

为什么有些Java库使用静态newInstance函数而不是构造函数?,java,android,Java,Android,在为Android开发时,我遇到了一个类。我觉得奇怪的是,这个类没有公共构造函数,而是提供了具有完全相同用途的静态createBitmap函数 在句法上没有优势: Bitmap bm = new Bitmap(10, 10); Bitmap bm = Bitmap.createBitmap(10, 10); 我见过其他类也这样做,其中等价的静态函数通常命名为newInstance。原因是什么?您所描述的称为工厂方法。它之所以存在,是因为它提供了获取符合特定接口的对象的能力,但该接口可能具有不同

在为Android开发时,我遇到了一个类。我觉得奇怪的是,这个类没有公共构造函数,而是提供了具有完全相同用途的静态
createBitmap
函数

在句法上没有优势:

Bitmap bm = new Bitmap(10, 10);
Bitmap bm = Bitmap.createBitmap(10, 10);

我见过其他类也这样做,其中等价的静态函数通常命名为
newInstance
。原因是什么?

您所描述的称为工厂方法。它之所以存在,是因为它提供了获取符合特定接口的对象的能力,但该接口可能具有不同的底层实现

对于(一个完全任意且琐碎的)示例,Factory方法可能会选择为您提供LinkedList对象而不是ArrayList对象,因为您指定的初始大小在LinkedList中可能具有性能优势


但是两个列表实现都符合IList接口,因此结果对象作为IList返回。

在第一种情况下,您需要实例化一个特定类型。在第二种情况下,由实现者决定返回哪种类型

我不熟悉位图,但另一个例子是EnumSet。当你打电话时:

EnumSet<SomeEnum> set = EnumSet.noneOf(SomeEnum.class);

这是工厂方法模式

这样做有两个主要原因:

  • 它允许将来不总是每次返回新实例的可能性。例如,
    Integer.valueOf(int)
    将重新使用它已经创建的相同整数对象,如果这些值介于-127和128之间。哪些是代码中使用的最常见的整数值,因此我们不需要JVM制作数千个相同实例的副本(每个副本都占用内存),只需重用相同的实例即可

  • 它允许静态方法在调用方不知道的情况下返回子类。如果将工厂方法与其他设计模式(如代理或适配器)相结合,以返回类的修改版本,这将非常有用


  • 编辑:这个问题涉及的内容如下:

    这就是工厂模式。整个要点是从静态类创建类,因此可以隐藏类的编程细节(安全措施)

    资料来源:

    意图:

    创建对象而不向用户公开实例化逻辑 客户通过公共接口引用新创建的对象

    例如:

    public class ProductFactory{
        public Product createProduct(String ProductID){
            if (id==ID1)
                return new OneProduct();
            if (id==ID2) return
                return new AnotherProduct();
            ... // so on for the other Ids
    
            return null; //if the id doesn't have any of the expected values
        }
        ...
    }
    
    另一个固体来源:


    这是《有效的Java》一书中最重要的部分。你可以看一下。这只是一个设计偏好静态工厂,就像用驼峰大小写方法名一样。@RohitJain我意识到这对Java程序员来说是一个愚蠢的问题。只是我从未在其他语言中见过这种模式。由于我对Java的知识有限,它看起来像是另一个臃肿的语言细节。我现在明白了,我想我太熟悉那些不真正隐藏实现细节的语言了。你是说那些不提供封装的语言?甚至C也有这种能力。问题()注释中链接的“有效Java第二版”一书明确指出——注意,静态工厂方法与设计模式中的工厂方法模式不同[Gamma95,第107页]。本项中描述的静态工厂方法在设计模式中没有直接等效--@RobertHarvey对我来说,封装总是关于类本身的实现细节,就像ArrayList的隐藏内部数组。它从未涉及到获取与请求的对象完全不同的对象。在C语言中,如果我想要链表的行为,我知道显式地要求它。@LastCoder:我已经相应地修改了我的答案。但这本书并没有解释他们为什么会做出这样的评论,从工厂模式来看,它似乎有许多与“静态工厂方法”相同的动机。
    public class ProductFactory{
        public Product createProduct(String ProductID){
            if (id==ID1)
                return new OneProduct();
            if (id==ID2) return
                return new AnotherProduct();
            ... // so on for the other Ids
    
            return null; //if the id doesn't have any of the expected values
        }
        ...
    }