【问题标题】:ClassName of annonymous inner class is same - obj.getClass().getName()匿名内部类的 ClassName 相同 - obj.getClass().getName()
【发布时间】:2018-07-22 07:50:29
【问题描述】:

我正在创建 20 个新的内部类并重写了一个打印类名的方法。但是每次我得到这 20 个实例时,类名都是相同的。我的要求是为每个人获取不同的类名。我怎样才能做到这一点?任何指针都非常感谢 - 谢谢。

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class TestClassName {
    public static void main(String[] args) {


    List<? super Check>  list=   IntStream.rangeClosed(1, 20).mapToObj(e -> new Check() {

        @Override
        public void execute() {
            System.out.println(this.getClass().getName());

        }
    }).collect(Collectors.toList());

list.forEach(i -> ((Check)i).execute());
}
}

interface Check {
public abstract void execute();
}

输出

TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
TestClassName$2
    TestClassName$2

【问题讨论】:

  • 您只是在创建同一个匿名类的新实例。您不能在运行时创建新的类名(至少不容易)。您对此有什么想法?你想完成什么?
  • 我有一个向外部客户端公开的注册服务,可以为某些节点类型多次注册他们的服务,因此客户端可以创建尽可能多的对象,并且可以一次又一次地注册相同的节点类型.我想通过过滤它们的类名来避免执行相同的对象。
  • 某种类型的所有对象都将具有相同的类名。您可能需要一些(唯一的)标识符来识别每个注册。
  • 为什么不直接使用== 来测试对象身份呢?或者,如果您想使用equals() 来区分对象,请为注册表使用某种基于散列的集合类型。 (请注意,equals()== 相同,除非您的对象覆盖了默认行为。)
  • 我认为将设计基于基本 Object 方法的正确实现是合理的。这是使用许多 Java 集合的要求。

标签: java lambda foreach java-8 inner-classes


【解决方案1】:

简单:您正在重复实例化 same 内部类。

您的代码只包含一个内部类!

当您执行 new Integer() 20 次时,您会假设每次都会创建一个新的 Integer 类吗?当然不是。类保持不变,你只是得到同一个类的不同对象。

为了创建多个匿名内部类,实际上必须在源代码中重复添加定义!

要解决您的问题,您需要一个使用对象的“身份”而不是它们的类的注册表!

【讨论】:

    【解决方案2】:

    您只是在创建同一个匿名类的新实例。在运行时添加新类非常困难(或者可能是不可能的,具体取决于安装的安全管理器)。这几乎肯定不是您需要做的。

    从 cmets 到您的问题,您似乎只需要区分界面实例。为此,最简单的方法是在注册表中使用哈希映射。

    大多数映射实现(如HashMap)依赖于所谓的值相等:如果equals() 返回true,映射将两个引用视为同一个对象。在某些情况下(我不知道您的是否属于其中之一),这不是正确的语义,您需要对象标识(也就是说,只有当它们是 == 时,两个引用才被视为相同)。为此,您可以在注册表中使用 IdentityHashMap 而不是 HashMap。它使用System.identityHashCode()== 来实现映射,而不使用对象的equals()hashCode() 实现。

    在您的 cmets 中,您表示担心客户端是否正确实施 equals()hashcode()。这让我觉得借用麻烦,但如果你想解决这个问题,IdentityHashMap 也可以在这里完成工作。或者,您可以用抽象基类替换您的接口,该基类将equals()hashCode() 实现为final 方法,这些方法委托给它们的Object 实现,但这似乎很笨拙,而且可能不可行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-06
      • 1970-01-01
      • 1970-01-01
      • 2014-07-17
      • 1970-01-01
      • 2019-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多