【问题标题】:Java enum synthetic arguments for constructors构造函数的 Java 枚举合成参数
【发布时间】:2014-07-30 02:42:08
【问题描述】:

请查看Synthetic Arguments。枚举构造函数有两个额外的合成参数。

请看部分:

另一个例子:Java 枚举类

如您所见,它节省了相当多的代码,但还添加了合成字段、方法和构造函数参数。如果您已经定义了自己的构造函数,并带有自己的一组参数。

是否存在枚举构造函数没有任何合成参数的情况。

抱歉没有提供足够的细节。

【问题讨论】:

  • 我在这篇文章中找不到任何综合论据。考虑使用适当的示例编辑您的问题,以便我们知道您的问题实际上是关于什么的。
  • @Pshemo 信息在那里,但我同意阅读一篇长文只是为了理解这个问题是相当令人沮丧的。不过,这个问题中提供的代码示例对我来说意义不大。

标签: java parameters constructor enums synthetic


【解决方案1】:

读过这篇文章,我会说答案是否定的。文章解释了一个典型的枚举,例如:

enum Colours {
    RED, BLUE;
}

变成:

final class Colours extends java.lang.Enum {
    public final static Colours RED = new Colours("RED", 0);
    public final static Colours BLUE = new Colours("BLUE", 1);

    private final static values = new Colours[]{ RED, BLUE };

    private Colours(String name, int sequence){
        super(name, sequence);
    }

    public static Colours[] values(){
        return values;
    }

    public static Colours valueOf(String name){
        return (Colours)java.lang.Enum.valueOf(Colours.class, name);
    }
}

Colours 构造函数的参数被认为是合成的(即它们已由编译器生成以确保“东西有效”)。因此,综合论点似乎是不可避免的,因为它们是将枚举转换为真实类的必要部分。

唯一的可能性是如果枚举没有值 - Java 仍然创建合成字段吗?直觉上,答案是肯定的。 好的,但我为什么要关心? 部分中的文章支持这一点。在这里作者展示了一个空枚举仍然有两个参数计数,当用反射查看时。

【讨论】:

    【解决方案2】:

    查看 TimeUnit 的 Concurrent 类的源代码。它是一个有自己的方法的枚举。 您可以使用枚举,就像它们本身就是类一样。

    http://fuseyism.com/classpath/doc/java/util/concurrent/TimeUnit-source.html

    这是我的一个例子:

    public enum ExampleEnum {
        ENUM_1 ( "ENUM_1", 1, Color.GREEN ) {
            @Override
            public void doMethingWeird( String stringToEnum ) {
                //Implementation goes here;
            }
        }, 
        ENUM_2 ( "ENUM_2", 2, Color.BLACK ) {
            @Override
            public void doMethingWeird( String stringToEnum ) {
                //Implementation goes here;
            }
        }, 
        ENUM_3 ( "ENUM_3", 3, Color.WHITE ){
            @Override
            public void doMethingWeird( String stringToEnum ) {
                //Implementation goes here;
            }
        };    //Don't forget the semicolon ';' after the enums, to separate them from the methods;
    
        //You can have static constants;
        private static final Object object = new Object();
    
        private final String enumName;
        private final int enumNumber;
        private final Color enumColor;  //why not?
    
        //CONSTRUCTOR IT MUST BE PRIVATE
        private Effect( String enumName, int enumNumber, Color enumColor ){
                this.enumName = enumName;
                this.enumNumber = enumNumber;
                this.enumColor = enumColor;
        }
    
        //you can have abstract methods and implement them on the enums.
        public abstract void public void doMethingWeird( String stringToEnum );
    
        public String getEnumName() {
                return enuName;
        }
    
        public int getEnumNumber() {
                return enumNumber;
        }
    
        public Color getEnumColor() {
                return enumColor;
        }
    }
    

    我希望我有所帮助。

    【讨论】:

    • 我的意思是“doSomethingWeird”,而不是“doMethingWeird”。但我希望它会有所帮助。
    【解决方案3】:

    我遇到了同样的问题,有一个带有树构造函数和参数的枚举。进行反射并获取构造函数参数,您将获得一个 String 和一个额外的 int 作为前 2 个参数。我想知道他们是从哪里来的。调试后发现 Enum 类有一个受保护的构造函数,它使用的是前 2 个参数。

    我通过添加一个不带参数的构造函数进行了测试,并且还添加了两个额外的参数。

    来自 Enum.java 的带有构造函数的代码:

    /**
     * Sole constructor.  Programmers cannot invoke this constructor.
     * It is for use by code emitted by the compiler in response to
     * enum type declarations.
     *
     * @param name - The name of this enum constant, which is the identifier
     *               used to declare it.
     * @param ordinal - The ordinal of this enumeration constant (its position
     *         in the enum declaration, where the initial constant is assigned
     *         an ordinal of zero).
     */
    protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }
    

    要检测这种情况,可以使用反射构造函数的isEnum()方法,跳过2个参数。

    Constructor<?> constructor;
    
    private boolean isEnum() {
        return constructor.getDeclaringClass().isEnum();
    }
    

    【讨论】:

      猜你喜欢
      • 2011-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-17
      • 1970-01-01
      • 2011-10-30
      • 1970-01-01
      相关资源
      最近更新 更多