当前位置: 首页 > 知识库问答 >
问题:

接口类Java中的静态工厂方法

白青青
2023-03-14

我在读有效的Java课本。第一项是关于使用静态工厂方法而不是公共构造函数。我的疑问是,如果我正在指定接口我如何在接口中指定静态工厂方法?因为Java不支持interface内部的静态方法。教材指定了如何创建包含公共静态工厂方法的不可实例化类。但是这些方法如何访问实现类的私有构造函数呢?

教材中说,如果要定义接口类型,请创建一个不可实例化的类types,并在该类中包含静态工厂方法。但是types类中定义的方法如何访问interface type具体实现的私有构造函数

编辑:-以下句子引自课本。请给我解释一下它的意思

接口不能有静态方法,因此按照惯例,名为类型的接口的静态工厂方法被放在名为类型的不可实例化类(第4项)中

编辑:-摘自Joshua Bloch的有效Java:Item1-静态工厂方法

     public interface Foo{ //interface without plural 's' (question 1)
     public void bar();
 }
 public abstract class Foos(){ // abstract factory with plural 's' (question 1)
    public static Foo createFoo(){
        return new MyFoo();
    }
    private class MyFoo implements Foo{ // a non visible implementation (question 2)
       public void bar(){}
    }
 }

我的问题是静态方法createFoo()如何调用myFoo的私有构造函数

共有2个答案

彭阳朔
2023-03-14

这个问题在Java 8中得到解决。现在接口可以有静态方法。更多详情请访问:http://www.techempower.com/blog/2013/03/26/Everyth-about-java-8/

杭令
2023-03-14

您可以将工厂定义为返回接口,但它在内部创建一个具体的类。

例如:

public Interface I { }

private class Impl implements I {
}

I buildI() {
    return new Impl();
}

诀窍是用包私有(或者即使它们是内部类私有)构造函数创建实现,然后只有工厂才能构建它们。

这种方法的强大之处在于,工厂可以根据需求构建适当的实现,而且所有的事情对用户来说都是不可见的。例如,当使用工厂创建枚举集时,根据为其构建枚举枚举中的条目数,会有多个内部实现。超快版本使用少于64个条目的long forenums上的位字段,较慢版本使用较长的枚举。

要为工厂指定接口,您需要做的全部工作是:

public interface Factory {
   I buildI();
}

现在人们可以用setFactory(new FactoryImpl())调用您;然后您可以调用factory.buildi(),然后他们的代码返回具体的实现。

您可以进一步使用泛型:

public interface GenericFactory<T> {
    T buildInstance();
}

然后您的setFactory变为:

public void setFactory(GenericFactory<I> factory);

要创建一个工厂,他们会:

public class FactoryImpl implements GenericFactory<I> {
     @override
     I buildInstance() {
        return new impl();
     }
}

但现在您可以对任何需要工厂的东西使用相同的工厂类,只需更改泛型要求即可。

它可以调用私有构造函数的原因很简单--它是在同一个类中声明的!

在一个Java文件中,您可以使用私有构造函数创建类。然后在类中定义静态方法,即使它是静态的,它仍然具有访问构造函数所需的特权。

如果工厂和实现在不同的类中,那么它们将被放置在相同的包中,并且该方法将package private而不是private。

 类似资料:
  • 此具有方法 我迷路了...有人能解释一下吗

  • 我有以下静态工厂实现: FirstHandler和SecondHandler都实现以下接口: 请求对象是两个附加类的基类,其中包含请求的附加数据。 在我的主课上,我试着做以下几点: 请求的源由HTTP请求体提供,它可以解析为请求子类中的任何一个。我得到的编译错误是:“必需类型:捕获?扩展请求,提供请求”。 我知道请求对象不会扩展自身,这听起来很奇怪,但有没有办法这样调用handle方法?

  • 问题内容: 什么是静态工厂方法? 问题答案: 我们避免直接访问数据库连接,因为它们占用大量资源。因此,如果我们低于限制,我们将使用静态工厂方法来创建连接。否则,它将尝试提供“备用”连接,如果不存在则失败,并显示异常。

  • 在Java中是否有一个静态工厂方法来创建队列? 或 但无法找到对队列(或出队列)进行同样操作的方便方法。我找到的唯一解决办法是:

  • 错误:org.mockito.exceptions.misusing.missingMethodInvocationException:when()需要一个参数,该参数必须是“mock上的方法调用”。例如:when(mock.getArticles()).thenreturn(articles); 此外,此错误可能会出现,因为:1。您可以存根:finall/private/equals()/has

  • 问题内容: 首先,如果这是一个非常愚蠢的问题,请原谅我,我只是想学习这种语言的核心。我正在阅读《有效的Java》,并且第一章讨论了静态工厂方法与构造方法。他们的利弊。令我困惑的几件事是: 静态工厂方法返回的对象的类是非公共的 -究竟是什么意思? 与构造函数不同,每次调用静态工厂方法都不需要创建新对象 -这是怎么发生的?我仅调用工厂方法来获取新对象,是否将检查方法放入工厂方法中以检查对象是否已存在?