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

Man*_*wam 9 java static-factory

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

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

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

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

编辑: - 取自Effective Java作者:Joshua Bloch:第1项 - 静态工厂方法

     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(){}
    }
 }
Run Code Online (Sandbox Code Playgroud)

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

Tim*_*m B 7

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

例如:

public Interface I { }

private class Impl implements I {
}

I buildI() {
    return new Impl();
}
Run Code Online (Sandbox Code Playgroud)

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

这种方法的强大之处在于工厂可以根据需求构建适当的实现,并且这一切都发生在用户不可见的地方。例如,当你创建一个EnumSet工厂使用有多个内部实现取决于有多少项有在EnumEnumSet正在修建的。一个使用位域的超快速版本,用于Enums少于 64 个条目的 long for ,一个较慢的版本用于更长的枚举。

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

public interface Factory {
   I buildI();
}
Run Code Online (Sandbox Code Playgroud)

现在人们可以打电话给你,setFactory(new FactoryImpl());你可以打电话factory.buildI(),他们的代码然后返回具体的实现。

您可以更进一步并使用泛型:

public interface GenericFactory<T> {
    T buildInstance();
}
Run Code Online (Sandbox Code Playgroud)

然后你setFactory变成:

public void setFactory(GenericFactory<I> factory);
Run Code Online (Sandbox Code Playgroud)

要创建工厂,他们会执行以下操作:

public class FactoryImpl implements GenericFactory<I> {
     @override
     I buildInstance() {
        return new impl();
     }
}
Run Code Online (Sandbox Code Playgroud)

但是现在您可以将相同的工厂类用于绝对需要工厂的任何事物,只需更改泛型要求即可。

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

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

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


Man*_*wam 5

JAVA 8中解决了此问题。现在,接口可以具有静态方法。此处有更多详细信息:-http: //www.techempower.com/blog/2013/03/26/everything-about-java-8/