Java 如何泛化使用对象缓存的工厂方法?
我试图为一组从公共父级继承的类创建一个静态工厂方法。我的想法是实现类似于String的intern()方法的东西——我希望在使用等效对象时使用factory方法来使用单个对象(而不是使用数千个等效对象) 请注意,大多数子类没有字段,但其中一些可能有一些字段并具有不同的构造函数参数(在这种情况下,我会覆盖子类的equals和hashCode),因此每个类只使用一个单例将不起作用(而且我也不想使用单例) 我已经编写了下面的代码,但是对于每个子类,我必须在工厂方法中复制几乎相同的代码。我试着用一种通用的方法写它,但不知道怎么写 有没有办法避免所有这些丑陋的代码重复Java 如何泛化使用对象缓存的工厂方法?,java,generics,factory,Java,Generics,Factory,我试图为一组从公共父级继承的类创建一个静态工厂方法。我的想法是实现类似于String的intern()方法的东西——我希望在使用等效对象时使用factory方法来使用单个对象(而不是使用数千个等效对象) 请注意,大多数子类没有字段,但其中一些可能有一些字段并具有不同的构造函数参数(在这种情况下,我会覆盖子类的equals和hashCode),因此每个类只使用一个单例将不起作用(而且我也不想使用单例) 我已经编写了下面的代码,但是对于每个子类,我必须在工厂方法中复制几乎相同的代码。我试着用一种通用
public class Parent {
protected static final Map<Parent, WeakReference<Parent>> pool = Collections.synchronizedMap(new WeakHashMap<>());
}
public class Child extends Parent
{
final int field1;
final int field2;
// possibly more fields
private Child(int field1, int field2) {
this.field1 = field1;
this.field2 = field2;
}
public static Child newChildClass(int field1, int field2) {
Child child = new Child(field1, field2);
Child obj = (Child)pool.get(child).get();
if (obj == null)
pool.put(child, new WeakReference<>(child));
return obj;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Child that = (Child) o;
return field1 == that.field1 && field2 == that.field2;
}
@Override
public int hashCode() {
return Objects.hash(getClass(), field1, field2);
}
}
公共类父类{
受保护的静态最终映射池=Collections.synchronizedMap(new WeakHashMap());
}
公共类子级扩展父级
{
最后的int字段1;
最后的int字段2;
//可能还有更多的领域
私生子女(int field1、int field2){
此字段1=字段1;
this.field2=field2;
}
公共静态子newChildClass(int field1,int field2){
孩子=新孩子(字段1,字段2);
Child obj=(Child)pool.get(Child.get();
if(obj==null)
pool.put(child,新WeakReference(child));
返回obj;
}
@凌驾
公共布尔等于(对象o){
如果(this==o)返回true;
如果(o==null | | getClass()!=o.getClass())返回false;
子对象=(子对象)o;
返回field1==that.field1&&field2==that.field2;
}
@凌驾
公共int hashCode(){
返回Objects.hash(getClass(),field1,field2);
}
}
请注意,此缓存逻辑已损坏。它假定散列相等是对象相等,但事实并非如此。同一缓存项可以映射到多组参数。“我想这不是你想要的。”吉恩,你能解释一下为什么吗?散列可能会发生冲突。不能保证int hash=Objects.hash(ChildClass.class,)
将计算该类和参数集的唯一编号。因此,假设带有参数P的类A散列到与带有参数Q的类B相同的值。您可以调用A(P)的工厂,将其放入缓存中。然后给工厂打电话要B(Q)并把A(P)拿回来。@Gene我现在明白你的意思了,谢谢。现在应该修好了。