Java 如何泛化使用对象缓存的工厂方法?

Java 如何泛化使用对象缓存的工厂方法?,java,generics,factory,Java,Generics,Factory,我试图为一组从公共父级继承的类创建一个静态工厂方法。我的想法是实现类似于String的intern()方法的东西——我希望在使用等效对象时使用factory方法来使用单个对象(而不是使用数千个等效对象) 请注意,大多数子类没有字段,但其中一些可能有一些字段并具有不同的构造函数参数(在这种情况下,我会覆盖子类的equals和hashCode),因此每个类只使用一个单例将不起作用(而且我也不想使用单例) 我已经编写了下面的代码,但是对于每个子类,我必须在工厂方法中复制几乎相同的代码。我试着用一种通用

我试图为一组从公共父级继承的类创建一个静态工厂方法。我的想法是实现类似于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我现在明白你的意思了,谢谢。现在应该修好了。