通用类型 - 访问超类中的当前类

时间:2015-07-30 06:03:39

标签: java generics superclass

我有两节课。我的第一个被称为"经理"并依赖于我的第二课" ManageAble"。这种依赖是通过泛型类型进行的,这是一个类参数,你可以在Manager的代码中看到:

public class ManageAble {

 private int id;
 private Manager<?> manager;

 protected ManageAble() {
 }

 @SuppressWarnings("unused")
 // used by reflection
 private final <T extends ManageAble> void construct(Manager<T> pManager,
        final Integer pID) {
    manager = pManager;
    id = pID;
 }

 @SuppressWarnings("unused")
 // used by reflection
 private final void deconstruct() {
    manager = null;
    id = -1;
 }

 protected boolean isAttatched() {
    return manager != null;
 }

 public final <T extends ManageAble> Manager<T> getManager() {
    if (manager != null) {
        try {
            @SuppressWarnings("unchecked")
            Manager<T> castedManager = (Manager<T>) manager;
            return castedManager;
        } catch (ClassCastException pCce) {
            // returns null
        }
    }
    return null;
 }

 public final int getID() {
    return id;
 }

 @Override
 public String toString() {
    return "[" + id + "] - " + manager;
 }
}

方法&#34;注册&#34;班级&#34;经理&#34;将在类#34; ManageAble&#34;的构造函数中调用。但是我需要弄清楚,如果我的当前对象是一个类的实例,它可以用作参数&#34; pType&#34;在方法&#34;注册&#34;。以下是&#34; ManagerAble&#34;的代码:

public class Manager<Type extends ManageAble> {

 private final Map<Integer, Type> managed = new HashMap<Integer, Type>();
 private final Method construct = getManageAbleMethod("construct",
        new Class[] { Manager.class, Integer.class });
 private final Method deconstruct = getManageAbleMethod("deconstruct", null);

 public final boolean isManaging(final ManageAble pEntity) {
    if (pEntity != null) {
        return pEntity.equals(managed.get(pEntity.getID()));
    }
    return false;
 }

 public final boolean detatch(final ManageAble pEntity) {
    if (isManaging(pEntity)) {
        managed.remove(pEntity.getID());
        try {
            Object[] param = null;
            deconstruct.invoke(pEntity, param);
        } catch (IllegalAccessException | IllegalArgumentException
                | InvocationTargetException e) {
            // won't happen
        }
        return true;
    }
    return false;
 }

 public final synchronized boolean attatch(final Type pEntity) {
    if (pEntity != null)
        if (!isManaging(pEntity) && !pEntity.isAttatched()) {
            int id = getFreeID();
            managed.put(id, pEntity);
            try {
                construct.invoke(pEntity, new Object[] { this, id });
            } catch (IllegalAccessException | IllegalArgumentException
                    | InvocationTargetException e) {
                // won't happen
            }
            return true;
        }
    return false;
 }

 private final int getFreeID() {
    int id = 0;
    Set<Integer> idsInUse = managed.keySet();
    while (idsInUse.contains(id))
        id++;
    return id;
 }

 private final Method getManageAbleMethod(final String pMethodName,
        final Class<?>[] pParam) {
    try {
        Method m = ManageAble.class.getDeclaredMethod(pMethodName, pParam);
        m.setAccessible(true);
        return m;
    } catch (NoSuchMethodException | SecurityException e) {
        return null;
    }
 }
}

正如您所看到的,在我用注释而不是泛型类型参数的地方,我不知道如何强制参数成为定义构造函数的类。

有没有办法在其超类中访问当前类的泛型类型?

感谢您的帮助:)

编辑:我将代码更新为目前为止所获得的代码。我或多或少地通过丑陋的尝试/捕捉和反思来解决我的问题......有什么更好的想法吗?

1 个答案:

答案 0 :(得分:0)

我认为,为了满足您的要求,您的ManageAble课程也应该是通用的。像

这样的东西
public class ManageAble<T>  {

    private final int id;

    protected ManageAble(Manager<? super T> pManager) {
        id = pManager.register((T) this);
    }

    public final int getID() {
        return id;
    }

    @Override
    public String toString() {
        return "[" + id + "]";
    }

}

当然,Manager会变成:

public class Manager<Type extends ManageAble<Type>> {
...

然后您可以像这样使用它:

class Foo extends ManageAble<Foo> {

    public Foo(Manager<? super Foo> pManager) {
        super(pManager);
    }
}    

Manager<Foo> mg = new Manager<>();
Foo f = new Foo(mg);