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

2022-09-04 20:53:51

我正在阅读有效的java教科书。第一项是关于使用静态工厂方法而不是公共构造函数。我的疑问是,如果我指定一个如何指定一个静态工厂方法?因为 java 不支持 内部的静态方法。该教科书指定了有关创建包含公共静态工厂方法的不可实例化类的信息。但是,这些方法如何访问实现类的私有构造函数呢?InterfaceInterfaceinterface

教科书说,如果你正在定义一个 ,创建一个不可实例化的类,并在该类中包含静态工厂方法。但是,在类中定义的方法如何访问具体实现的私有构造函数Interface TypeTypesTypesInterface Type

编辑:- 下面的句子引用自教科书。请解释一下它的含义

“接口不能有静态方法,因此按照惯例,名为 Type 的接口的静态工厂方法被放在名为 Types 的不可检验类(Item 4)中 "

编辑:- 摘自Joshua Bloch的《Effective Java》:Item1 - Static Factory Method

     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


答案 1

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

例如:

public Interface I { }

private class Impl implements I {
}

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

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

这种方法的强大之处在于,工厂可以根据要求构建适当的实现,并且一切都以无形的方式发生在用户身上。例如,当您使用工厂创建一个时,有多个内部实现,具体取决于正在构建的条目中有多少个条目。在长 for 上使用位字段的超快速版本,条目少于 64 个,较慢的版本用于较长的枚举。EnumSetEnumEnumSetEnums

要为工厂指定接口,您需要做的就是:

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 文件中,您可以使用私有构造函数创建类。然后,在类中定义静态方法,即使它是静态的,它仍然具有访问构造函数所需的特权。

如果工厂和实现位于不同的类中,则它们将被放置在同一个包中,并且该方法将包设为私有而不是私有。


答案 2

Java 8最终允许接口具有静态方法。

有关详细信息,请参阅 TechEmpower 博客的存档副本


推荐