当前位置: 首页 > 面试题库 >

单例,枚举和匿名内部类

胡高寒
2023-03-14
问题内容

如您所知,有些人用1个Enum实例声明单例,因为JVM保证将始终存在单个实例,并且没有并发问题要处理…

因此,具有多个实例的枚举又如何呢?我们可以说枚举是共享公共接口的一种有序单例集吗?为什么?

public enum EnumPriceType {

    WITH_TAXES {
        @Override
        public float getPrice(float input) {
            return input*1.20f;
        }
        public String getFormattedPrice(float input) {
            return input*1.20f + " €";
        }
        },

    WITHOUT_TAXES {
        @Override
        public float getPrice(float input) {
            return input;
        }
    },
    ;

    public abstract float getPrice(float input);

    public static void main(String[] args) {
        WITH_TAXES.getFormattedPrice(33f);
    }

}

在此代码中,为什么它不起作用:WITH_TAXES.getFormattedPrice(33f);
如果不通过公共接口就不能调用公共方法,那么声明公共方法有什么用呢?我猜这就是为什么我看不到任何语法能够仅为枚举实例之一声明接口的原因。

编辑:

枚举实例似乎是一种特殊的匿名类。因此,我理解为什么您不能调用该方法。

我的问题与以下内容有关: 为什么匿名类不能实现接口 (除了它可能已经实现的接口之外)!

我完全理解为什么我们不能这样做:

Vehicle veh = new Vehicle() {
    public String getName() {
        return "toto";
    }
};
veh.getName();

(这里的getName不是替代)

我不明白的原因是为什么我们不能使用匿名类来做到这一点:

Runnable veh = new Vehicle() implements Runnable {
    @Override
    public void run() {
        System.out.println("i run!");
    }
};
veh.run();

否则会导致相同的结果。考虑一下:如果您不使用匿名类,则可以绝对扩展Vehicle类,然后使该子类实现您想要的任何其他接口…

我非常确定,如果可能的话,我们将能够以类型安全的方式调用WITH_TAXES.getFormattedPrice(33f),因为WITH_TAXES不是真正的EnumPriceType,而是一个EnumPriceType的子类,具有自己的接口,并且通过使用带有硬编码的WITH_TAXES的WITH_TAXES.getFormattedPrice(33f)进行调用,您可以在编译时知道正在调用的EnumPriceType子级。

所以我的问题是:有什么原因不能做到这一点?还是还没有完成?


问题答案:

您的枚举等效于以下普通类(实际上,这几乎是编译器将其转换为的类):

public abstract class EnumPriceType {

    public static final EnumPriceType WITH_TAXES = new EnumPriceType() {
        //getPrice() {...}
        //getFormattedPrice() {...}
    };

    public static final EnumPriceType WITHOUT_TAXES = new EnumPriceType() {
        //getPrice() {...}
    };

    public abstract float getPrice(float input);

    public static void main(String[] args) {
        WITH_TAXES.getFormattedPrice(33f);
    }
}

getFormattedPrice()方法在抽象类型上不可用,因此不能从main方法中调用。考虑如果将main方法重写为使用局部变量会发生什么:

public static void main(String[] args) {
    EnumPriceType foo = EnumPriceType.WITH_TAXES;
    foo.getFormattedPrice(33f);
}

这不能编译,因为getFormattedPrice()在基类上不可用。由于WITH_TAXES实例是的 匿名
子类EnumPriceType,因此无法将局部变量定义getFormattedPrice()为可见方法的类型。

作为元数据观察,这是强类型语言(例如Java)和“鸭子类型”语言(例如Ruby)之间的主要区别。getFormattedPrice()不管foo变量中包含什么类型的对象,Ruby都会很高兴地调用该方法。

作为另一个元数据观察,对于相同的不同常量enum使用不同的集合方法没有多大意义。如果不能将所需的所有内容作为抽象(或具体)方法放在基本枚举类型上,则可能是使用了错误的工具来解决问题。



 类似资料:
  • 本文向大家介绍Java匿名类,匿名内部类实例分析,包括了Java匿名类,匿名内部类实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Java匿名类,匿名内部类。分享给大家供大家参考,具体如下: 内部类 匿名类  首发日期 :2018-03-25 内部类: 在一个类中定义另一个类,这样定义的类称为内部类。【包含内部类的类可以称为内部类的外部类】 如果想要通过一个类来使用另一个类,可以定

  • 在以下片段中: 有没有办法从内部匿名类引用匿名类的外部实例? 第二个错误是在解决方案上,我在这里找到了一个匿名内部类的外部类的关键字。这些问题似乎共享一些概念和问题空间,但性质不同。

  • 问题内容: 这不是卡住我的问题,而是我正在寻找一种编写代码的整洁方法。 本质上,我正在编写一个事件驱动的应用程序。用户触发一个事件,该事件被发送到适当的对象,然后这些对象处理事件。现在,我正在编写偶数处理程序方法,并且希望使用switch语句确定如何处理事件。现在,在我研究通用结构时,事件类非常简单: 然后,在另一堂课中,我会看到类似以下内容的内容: 我会 喜欢 做的就是这样的事情(尽管我当然会坚

  • 问题内容: 枚举被认为是单例的最佳方式,其原因之一是它隐式继承。 但是,枚举如何防止单例的反序列化问题? 问题答案: 序列化机制以特殊的特定方式处理它们。但是,可以通过定义返回唯一实例的方法来对传统的单例进行反序列化。有关示例,请参见http://www.oodesign.com/singleton- pattern.html 。

  • 问题内容: 请看下面的代码: 在上面的代码中,在方法ModifyList()中声明的匿名内部类的实例能够访问传递给该方法的参数。AFAIK Java为内部类创建一个单独的字节码文件。 谁能解释一下Java在字节码级别上如何处理这些局部变量绑定?我的意思是,Java如何精确跟踪对作为参数传递给该方法的对象的引用? 任何帮助将不胜感激! [抱歉我的英语不好! 如果您理解我的问题,请编辑这篇文章,并删除

  • 问题内容: 我正在编写C#Wicket实现,以加深对C#和Wicket的理解。我们遇到的问题之一是Wicket大量使用匿名内部类,而C#没有匿名内部类。 因此,例如,在Wicket中,您可以这样定义一个链接: 由于Link是一个抽象类,因此它强制实现者实现onClick方法。 但是,在C#中,由于没有匿名内部类,因此无法做到这一点。另外,您可以使用如下事件: 当然,这样做有两个缺点。首先,可以有多