Joshua Bloch的高效Java:Item1-静态工厂方法
我正在阅读Joshua Bloch的Joshua Bloch的高效Java:Item1-静态工厂方法,java,design-patterns,factory,effective-java,Java,Design Patterns,Factory,Effective Java,我正在阅读Joshua Bloch的有效Java,我对Item1静态工厂方法有疑问 引用[Bloch,第7页] 接口不能有静态方法, 所以按照惯例,静态工厂 名为Type的接口的方法 都放在不可实例化的类中 命名类型。例如,Java 集合框架,提供 不可修改的集合,已同步 收藏等等。几乎全部 这些实现中的一个是导出 通过静态工厂方法在一个 不可定类 (java.util.Collections)。班级 返回的对象的 非公有制 嗯。当查看源代码时,我看到了java.util.Collection接
有效Java
,我对Item1静态工厂方法有疑问
引用[Bloch,第7页]
接口不能有静态方法,
所以按照惯例,静态工厂
名为Type的接口的方法
都放在不可实例化的类中
命名类型。例如,Java
集合框架,提供
不可修改的集合,已同步
收藏等等。几乎全部
这些实现中的一个是导出
通过静态工厂方法在一个
不可定类
(java.util.Collections)。班级
返回的对象的
非公有制
嗯。当查看源代码时,我看到了java.util.Collection
接口和java.util.Collections
带有私有构造函数的类(非实例化类)。我看到不可实例化的类集合具有所有静态方法,就像Bloch所说的那样。但我没有看到布洛赫所说的两个类之间的联系
接口不能有静态方法,因此按照惯例,名为Type的接口的静态工厂方法放在名为Type的不可实例化类中。
有谁能向我指出显而易见的事情吗
他说的是什么意思
返回对象的类都是非公共的
这里是我获取java源代码的地方:,举个例子。它返回列表的一些实现。但是实现类的名称是不相关的。此外,所述类仅通过静态工厂方法构造
接口不能有静态方法,因此按照惯例,名为Type的接口的静态工厂方法被放在名为Types的不可实例化类中
重点是“Type[s]”上的复数“s”。因此,如果您的接口被称为Foo
,并且您希望创建一些名为MyFoo
的实现,那么按照惯例,您的工厂和实例化方法应该被称为Foos
返回对象的类都是非公共的
这意味着从工厂方法返回的对象类有一个私有或默认的可见性修饰符,如private class MyFoo{}
中所示,因此除了工厂方法外,它们不能通过任何其他方法实例化。因为您不能从私有内部使用new
操作符构造对象,也不能将私有类打包到其范围之外(反射除外)
e、 g:
1) 我不明白你的问题Collection
是接口,Collections
有一些工厂方法,如emptyList
2) 例如,由集合返回的列表实例。emptyList
是实现列表
接口的私有类的实例。它只是意味着集合
中的静态工厂方法(以及类似它的其他类)的返回类型是接口类型(例如列表
)而不是特定的实现类(例如,java.util.Collections.UnmodifiableList
),用户看不到的,因为这只会使事情复杂化并增加API的大小。假设您有一个名为List
的界面,并且希望使用静态工厂方法创建不同类型的列表。不能在列表
接口中定义静态工厂方法,因为它是一个接口。所以,您需要做的是创建一个类,该类返回实现列表的类的实例
public class ListFactory{
private ListFactory(){}
public static List makeArrayList(){...}
public static List makeLinkedList(){...}
public static List makeCrazyList(){...}
}
你不能这样做
public interface List{
public static List makeArrayList();
public static List makeLinkedList();
public static List makeCrazyList();
}
因为列表
是接口 我还有一个问题要问你。对于2
,将返回对象作为私有类的实例有什么好处?关于1
的精彩解释。我知道这一定更好。非常感谢你。对于2
:将返回对象作为私有类的实例有什么好处?您可以在API用户不注意的情况下切换实现,因为他从未使用new
自己构造过一个对象。因此,如果你需要重新实现一些东西,你可以创建一个新的版本,而不需要任何API更改。我发现我需要在内部类MyFoo中添加“static”修饰符,以便编译它。。。否则,我会得到一个错误,即不存在Foos的封闭实例。我做错什么了吗?@Mats_-SX:我刚刚读到一些关于这个的东西。基本上可以归结为,在内部MyFoo类中,您实例化了一个Foos实例并引用它。一个很好的例子是来自Guava的类,它包含用于List
实例的静态工厂函数。例如,您可以使用以下代码创建字符串列表:list list list=Lists.newArrayList(“first”、“second”、“third”)
另请参见。默认情况下,关于Bloch的任何内容对我来说都是加一的。从java 8开始,接口不能包含静态方法的限制被取消。
public interface Foo
static public class Factory
public Foo create(){..}
Foo foo = Foo.Factory.create();
public interface Foo
static public class Factory
public Foo create(){..}
Foo foo = Foo.Factory.create();