我正在阅读Functional Java库的源代码并注意到这一点:
public static <T> Option<T> none() {
return new None<T>();
}
我想知道他们为什么不总是返回一个单例参数,特别是因为None的等式实现:
private static final class None<A> extends Option<A> {
...
@Override
public int hashCode() {
return 31;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
return true;
}
}
所以我在Functional Java的论坛上搜索了一下,我找到了这个问题并回答:
是否可以设置它以便它不会为每次调用都创建一个新的None,我们可以在所有情况下使用单个对象来表示None吗?
不,但那么,谁在乎呢? JIT优化器现在可以很好地处理这些事情。
我的问题是JIT优化器如何以不必返回单例的方式处理它。我知道对象创建很便宜,但我认为单例会更便宜,在这种情况下它不会增加任何复杂性。
答案 0 :(得分:3)
不,我知道的Java VM并没有进行这样的优化。使用现代JVM,创建新对象实际上更便宜,而不是寻找现有的JVM。他们在这个FAQ中的含义是,短暂的,丢弃的对象并不会真正影响垃圾收集时间(但可能会增加GC频率)。此外,我可以想象JVM执行转义分析并在堆栈上而不是在堆上分配这样的对象。
但是我做认为这很浪费。查看java.lang.Integer
(和所有其他原始包装器)缓存或Optional.absent()
in Guava:
public static <T> Optional<T> absent() {
return (Optional<T>) Absent.INSTANCE;
}
在JDK中还有很多其他的优化:enum
是单例,Collections.emptyList()
总是返回相同的实例,等等。
答案 1 :(得分:1)
它更安全,否则我们需要依赖擦除。
创建对象可能比查找缓存对象更昂贵。请参阅java8&#39的可选:
43 private final static Optional<?> EMPTY = new Optional<>();
63 * There is no guarantee that it is a singleton.
69 @SuppressWarnings("unchecked")
70 public static<T> Optional<T> empty() {
71 return (Optional<T>) EMPTY;
72 }