Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Java, how to iterate on the constants of an interface?

Tags:

java

in an interface, I store constants in this way (I'd like to know what you think of this practice). This is just a dummy example.

interface HttpConstants {
    /** 2XX: generally "OK" */
    public static final int HTTP_OK = 200;
    public static final int HTTP_CREATED = 201;
    public static final int HTTP_ACCEPTED = 202;
    public static final int HTTP_NOT_AUTHORITATIVE = 203;
    public static final int HTTP_NO_CONTENT = 204;
    public static final int HTTP_RESET = 205;
    public static final int HTTP_PARTIAL = 206;

        ...
}

Is there a way I can iterate over all constants declared in this interface ?

like image 347
BuZz Avatar asked Mar 14 '12 10:03

BuZz


People also ask

Can we use interface for constants in Java?

Interface ConstantsA Java interface can contain constants. In some cases it can make sense to define constants in an interface. Especially if those constants are to be used by the classes implementing the interface, e.g. in calculations, or as parameters to some of the methods in the interface.

Can we define constants in interface?

Java programmers commonly define constants inside their interfaces, if it makes design sense. You can do so using variables in an interface because the values will be present instantly at runtime and their values shared among all classes implementing your interface, because they are static and final.

Should we use interface for constants?

The static import feature should always be considered as a replacement for this practice. Placing constants in an interface was a popular technique in the early days of Java, but now many consider it a distasteful use of interfaces, since interfaces should deal with the services provided by an object, not its data.

Can an interface have constant variables?

Yes, you can keep constants in interfaces.


Video Answer


2 Answers

Using reflection:

Field[] interfaceFields=HttpConstants.class.getFields();
for(Field f:interfaceFields) {
   //do something
}

But anyway, if you can redesign your class, I would recomend you to handle a static enum constants construction. So, suposing your class will contain always an int value for every constant:

enum HttpConstants {

    HTTP_OK(200), HTTP_CREATED(201), HTTP_ACCEPTED(202),
    HTTP_NOT_AUTHORITATIVE(203),HTTP_NO_CONTENT(204), 
    HTTP_RESET(205), HTTP_PARTIAL(206) /* ... */;

    private int value;

    HttpConstants(int aValue) {
        value=aValue;
    }

    public int getValue() {
        return value;
    }
}

Then, to loop on it:

    for(HttpConstants val: HttpConstants.values()) {
        int value=val.getValue();
            //...
    }

Thus, avoiding the access to the reflection API.

like image 166
Tomas Narros Avatar answered Sep 29 '22 16:09

Tomas Narros


I would create these constants as an enumeration. Enums in Java can have their own fields and methods, which very convenient for your case. So I would do this the following way:

enum HttpConstant {
    HTTP_OK(200),
    HTTP_CREATED(201),
    HTTP_ACCEPTED(202),
    HTTP_NOT_AUTHORITATIVE(203),
    HTTP_NO_CONTENT(204),
    HTTP_RESET(205),
    HTTP_PARTIAL(206);

    private final int id;

    HttpConstant(int id) {
        this.id = id;
    }

    int getId() {
        return id;
    }
}

Now the iteration is easy:

for (HttpConstant constant : HttpConstant.values()) {
    //Do something with the constant
}

This way it is also easy to add associate some new values with the constants, you just have to add new fields.

Right now you may use reflection:

Field[] interfaceFields = HttpConstants.class.getFields();
for (Field field : interfaceFields) {
    int constant = field.getInt(null);
    //Do something with the field
}

However, it is better to use the approach with enums because with reflection coding errors result in runtime exceptions instead of compile-time errors.

like image 22
Malcolm Avatar answered Sep 29 '22 16:09

Malcolm