访问匿名内部类变量

Emi*_*mil 5 java anonymous-class

如何从外部类访问我?

  HashSet<Integer> hs=new HashSet<Integer>(){
        int i=30;
    };
Run Code Online (Sandbox Code Playgroud)

我可以这样做

int k=new HashSet<Integer>(){
    int i=30;
}.i;
Run Code Online (Sandbox Code Playgroud)

但是,如果我得到"我",那么我就无法得到hashset的实例.有没有办法获得两者?问题只是出于好奇.它没有太多实际应用.我只是想知道它是否可以完成.

pol*_*nts 7

解决方案1:对象注册系统

提供的两个片段实际上是在存储对刚刚创建的匿名类实例的引用或立即访问其自定义字段之间做出选择.做一个似乎会放弃做另一个的能力.

实现折衷的一种方法是使用对象注册系统,并在匿名类中使用实例初始化程序(JLS 8.6)自行注册到此系统.

这是一个简单的概念验证,Object[]用于简单的注册系统:

    final Object[] registrar = { null };
    int k = new HashSet<Integer>(){
        { registrar[0] = this; }
        int i= 666;
    }.i;
    Set<Integer> set = (Set<Integer>) registrar[0];

    System.out.println(k); // 666
    System.out.println(set.getClass().isAnonymousClass()); // true
Run Code Online (Sandbox Code Playgroud)

本质上我们使用1元素Object[],在我们的匿名类的实例初始化器中,我们"注册" this到这个数组.请注意,这只是一个概念验证; 在生产代码中,您将使用比此更强大且类型安全的对象注册系统.


解决方案2:元组

如果您的匿名类可能有多个"字段",则此方法很有效.只需将它们全部打包成一个元组,确保this在匿名类中包含一个引用.

这是一个简单的概念验证,Object[]用于元组:

    Object[] tuple = new HashSet<Integer>(){
        Object[] tuple = { this, 666, 13, "XXX", "OMG ABUZE" };
    }.tuple;
    Set<Integer> set = (Set<Integer>) tuple[0];
    set.add(null);
    System.out.println(set.getClass().isAnonymousClass()); // true
    System.out.println(Arrays.toString(tuple));
    // [[null], 666, 13, XXX, OMG ABUZE]
Run Code Online (Sandbox Code Playgroud)

在生产代码中,您将使用CustomTuple更面向对象且类型安全的类.请注意,这是"我的方法如何返回2个值"问题的类似解决方案:只需返回1个值即可捕获所有这些信息.

  • 那很棒.我只是在玩Java.我不会在生产代码中这样做. (2认同)

And*_*anu 5

我想是对救援的反思:

HashSet<Integer> hs = new HashSet<Integer>() {
    int i = 30;
};
int i = hs.getClass().getDeclaredField("i").getInt(hs);
System.out.println(i);
Run Code Online (Sandbox Code Playgroud)

PS写完之后我觉得有点脏.