匿名内部类的ClassName相同-obj.getClass()。getName()

时间:2018-07-22 07:50:29

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

我正在创建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

2 个答案:

答案 0 :(得分:2)

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

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

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

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

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

答案 1 :(得分:1)

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

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

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

在您的评论中,您表示关注客户端是否正确实现equals()hashcode()。这给我带来了麻烦,但如果您想解决这个问题,IdentityHashMap也会在这里完成工作。另外,您可以用抽象基类来替换您的接口,该基类将equals()hashCode()作为final方法的委派给其Object实现的方法,但这似乎很繁琐,也许行不通。