繁体   English   中英

检查私有静态内部类的实例

[英]Checking if instance of private static inner class

这个问题的标题听起来像一个很好的思想实验。 可悲的是,事实并非如此。 让我们假设以下代码结构:

class Outer {
    private static class Inner implements SomeInterface {
        ...
    }
    public static SomeInterface returnInner() {
        return new Inner();
    }
}

是否有一种良好,干净的方式执行以下检查:

SomeInterface a  = A.returnInner();
if (a instanceof Outer.Inner)
    throw new Error("Ooops, something bad happened");

你认为这不是一个真实的例子吗? 检查Arrays类和方法asList(T ...) ,它返回自己的List<T>实现,它恰好是一个private static class ArrayList<T> (与通常的ArrayList无关 - 感谢Sun和Oracle如果没有你,我会怎么做)。 我需要检查传递给我的方法的对象是否不是这个包装类的实例,因为它没有实现add()方法(它使用AbstractList的实现 - 它抛出UnsupportedOperationException )。

真的没有好办法检查这个吗? 即使通过一些反思魔法?

有一种方法,但无论如何它都不是一个好方法:

// WARNINIG: This is very fragile, please try avoiding code like this.
if (theirList.getClass().getEnclosingClass() != null) {
    // theirList is an instance of an inner class
}

问题不是很难做到,而是结果变得非常不可靠:

  • 此代码拒绝List<T>可变实现 - 例如,如果您决定滚动自己的实现List<T>的嵌套类,它将被拒绝
  • 此代码将接受顶级只读实现 - 如果Oracle决定将实现移至顶级,则代码将停止工作。

出于这些原因,最好尝试添加到类中,捕获异常,并在调用者通过只读列表时采取您将要采取的任何替代方法。

这是一个可怕的,肮脏的,容易出错的练习,但你可以检查班级的名字。 内部的类名是封闭类的名称,后跟$和内部类的名称。 在这种情况下:

SomeInterface instance = Outer.returnInner();
if (instance.getClass().getName().equals(Outer.class.getName() + "$Inner")) {
    throw new RuntimeException("Ooops, something bad happened");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM