4

Alrighty, so I did some research on constants and how they should be designed and used. For my application, it made sense to have numerous enums that would group terms that are related to each other.

The idea being that as I develop web services with hundreds of parameters (many of which are used more than once) and methods, I could annotate using the values of the enums. Before this, there was a huge, disgusting Constants file with redundant and unmaintained values.

So, here's an enum I'd like to use:

package com.company.ws.data.enums;

/** This {@link Enum} contains all web service methods that will be used. **/
public enum Methods {

    /** The name of the web service for looking up an account by account number. **/
    FIND_ACCOUNT_BY_ACCOUNT_NUMBER("accountByNumberRequest");

    /** The String value of the web service method name to be used in SOAP **/
    private String value;

    private Methods(String value) {
        this.value = value;
    }

    /**
     * @return the String value of the web service method name to be used in
     *         SOAP
     */
    public String getValue() {
        return this.value;
    }
}

And here's a place I'd like to use it:

package com.company.ws.data.models;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

import com.company.ws.data.enums.Methods;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = **Methods.FIND_ACCOUNT_BY_ACCOUNT_NUMBER**, namespace = "com.company.ws")
public class AccountByNumberRequest{
}

So, if I try the above, I get the error Type mismatch: cannot convert from Methods to String which makes perfect sense. So, let's try accessing the actual value of the enum:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = **Methods.FIND_ACCOUNT_BY_ACCOUNT_NUMBER.getValue()**, namespace = "")
public class AccountByNumberRequest extends RequestByAccount {
}

Doing that, I get this error message: The value for annotation attribute XmlRootElement.name must be a constant expression.

So, can I use enums like I'm trying to? Can they be used in place of true static constant values as defined in a final class? Or am I in some weird compile-time state where the annotations are being evaluated before the enum itself is loaded and instantiated with its values? Guiding Resource: http://www.javapractices.com/topic/TopicAction.do?Id=1

4

2 回答 2

3

你不能。的值Methods.getValue()不是根据 JLS 的常量表达式,这是编译器告诉您的。

于 2013-11-12T20:02:10.330 回答
1

注释不会被评估或实例化。它们只是告诉编译器将附加数据(而不是代码)嵌入到已编译类中的指令,您可以稍后使用反射 API 对其进行查询。

因此,唯一可以设置为注释值的东西是常量 - 换句话说,在编译时已知的值可以简化为可以放在类的常量池中的东西:原始值,字符串,对其他类的引用,对枚举值的引用,上述数组。

因此,您不能从方法调用中设置注释值——它们的值只能在运行时执行后才知道。(好吧,如果方法总是返回相同的值,也许不会,但为了简化语言和编译器,Java 规范不需要编译器足够复杂来解决这个问题。)

于 2013-11-12T20:05:19.993 回答