Inheritance of Enums - java

To my understanding, Java enums are not extensible. So I wondered why enums are not final by definition. Just to make sure that I understand everything I had a look into the JLS 8 and found the following senentece:
An enum declaration is implicitly final unless it contains at least one enum constant that has a class body (§8.9.1).
Does that imply that I can create an extensible enum constant with, for example, an own method declaration, field, static- or object initializer?
So far I didn't found a way which leads me to the conclusion that enums could be always implicitly final. Where am I wrong?

As the description says, enum constants can have their own body in which methods that are defined in the enum itself are overridden. For example:
public enum ExampleEnum {
ONE,
TWO {
#Override
public void print() {
System.out.println("Two");
}
};
public void print() {
System.out.println(name());
}
}
In this example, the constant TWO has its own body with an overridden version of the print() method.
Note that it is not possible to extend an enum outside of the enum itself.

Related

How does TimeUnit.class enum operation work?

How exactly does the enum in the TimeUnit API work? Particularly what does the below syntax mean?
public enum Name {
CONSTANT { }
}
I have been following the enum tutorial here, but it doesn't really go into the details of the above syntax. What is the thing inside the constant? Is it an anonymous class with their own methods? Then what are all those methods outside of the constants? I'm so confused.
In the {} the "abstract" methods are implemented.
See it as the body of a class that extends - to follow your example - "Name".
So if you have a method in Name - let's say
public String someMethod(){ throw new AbstractMethodError(); /*Or default implementation.*/ }
then you'd have to implement that in
CONSTANT{
public String someMethod() { return "green eggs and ham"; }
}
And that's what is done in TimeUnit - it defines abstract methods for converting different units and the elements implement the conversion methods for their magnitude.
Enums are classes too, their constants can be viewed as instances of the class. If you look at a normal class, if you do something like:
Clz obj = new Clz() {}
you are creating an anonymous subclass. This is true for enum values too. The methods outside of the enum values are the methods available for all the enum values(think like the public interface with default implementations, if any). If you want to override a method for a particular enum value, that's the way to do it.

Inner Enum in non-static context

As I understood inner enums are always explicitly оr implicitly static in java. Which means I can't access instance fields from my inner enum class.
public class InnerEnum {
private enum SomeInnerEnum {
VALUE1() {
#Override
public void doSomething() {
// ERROR: WON'T COMPILE
// Cannot make static reference
// to non-static field i
System.out.println(i);
}
},
VALUE2() {
#Override
public void doSomething() {
// do something else with i
}
};
public abstract void doSomething();
}
private int i = 10;
}
I have found it pretty convenient to just override method in each enum constant, so I could use it in my outer class. Is it a bad programming style in java, because it is actually forbidden?
Is there any way to create inner enum with an access to my instance variables?
Thanks in advance.
Is there any way to create inner enum with an access to my instance
variables?
An enum is a compile time construct (predefined), and therefore any external data inside of one must be readily available to the compiler before runtime.
Unless you explicitly pass the variable (or some reference containing it, in your case this) down to the method inside the enum, you won't be able to reference it.
I have found it pretty convenient to just override method in each enum constant, so I could use it in my outer class. Is it a bad programming style in java, because it is actually forbidden?
There is nothing inherently wrong with overriding methods in your enum constants. As with any other language construct, it is not bad practice when used appropriately.
I'm not sure what you mean by "so I could use it in my outer class," but in general, enums should not be heavily dependent on external code. They are meant to describe a fixed set of constant values, and little or no coupling with other types should be required to accomplish that (beyond core types like primitives and strings, anyway). It strikes me as questionable design for an enum constant to access instance-level members of an outer type.

Why can't a class extend an enum?

I am wondering why in the Java language a class cannot extend an enum.
I'm not talking about an enum extending an enum (which can't be done, since java doesn't have multiple inheritance, and that enums implicitly extend java.lang.Enum), but a class that extends an enum in order to only add extra methods, not extra enumeration values.
Something like:
enum MyEnum
{
ASD(5),
QWE(3),
ZXC(7);
private int number;
private asd(int number)
{
this.number=number;
}
public int myMethod()
{
return this.number;
}
}
class MyClass extends MyEnum
{
public int anotherMethod()
{
return this.myMethod()+1;
}
}
To be used like this:
System.out.println(MyClass.ASD.anotherMethod());
So, can anyone provide a rationale (or point me to the right JLS section) for this limitation?
You can't extend an enum. They are implicitly final. From JLS § 8.9:
An enum type is implicitly final unless it contains at least one enum constant that has a class body.
Also, from JLS §8.1.4 - Superclasses and Subclasses:
It is a compile-time error if the ClassType names the class Enum or any invocation of it.
Basically an enum is an enumerated set of pre-defined constants. Due to this, the language allows you to use enums in switch-cases. By allowing to extend them, wouldn't make them eligible type for switch-cases, for example. Apart from that, an instance of the class or other enum extending the enum would be then also be an instance of the enum you extend. That breaks the purpose of enums basically.
In ancient days of pre Java 1.5 you would probably do enums like this:
public class MyEnum {
public static final MyEnum ASD = new MyEnum(5);
public static final MyEnum QWE = new MyEnum(3);
public static final MyEnum ZXC = new MyEnum(7);
private int number;
private MyEnum(int number) {
this.number = number;
}
public int myMethod() {
return this.number;
}
}
There are two important things about this figure:
private constructor that will not allow to instantiate the class from outside
actual "enum" values are stored in static fields
Even if it's not final when you'll extend it, you'll realize that compiler requires an explicit constructor, that in other turn is required to call super constructor which is impossible since that one is private. Another problem is that the static fields in super class still store object of that super class not your extending one. I think that this could be an explanation.
The whole point of an enum is to create a closed set of possible values. This makes it easier to reason about what a value of that enum type is -- easier for you the programmer, and also easier for the compiler (this closedness is what lets it handle enums efficiently in switches, for instance). Allowing a class to extend an enum would open up the set of possible values; at that point, what does the enum buy you that a regular class wouldn't?
I think an answer to why they did it this way comes from this question:
In your example, how would you instantiate a MyClass? Enums are never explicitly instantiated (via a new MyEnum()) by the user. You'd have to do something like MyClass.ASD but not sure how that would work.
Basically, I don't know what syntax would work for your proposed addition. Which is probably why they made them final etc...
EDIT ADDED
If the author of the original Enum planned ahead (unlikely), and you are not worried too much abut thread safety, you could do something like this: (BTW, I'd probably scream at anybody who actually did this in production code, YMMV)
public enum ExtendibleEnum {
FOO, BAR, ZXC;
private Runnable anotherMethodRunme; // exact Interface will vary, I picked an easy one
// this is what gets "injected" by your other class
public void setAnotherMethodRunMe(Runnable r) { // inject here
anotherMethodRunme= r;
}
public void anotherMethod() { // and this behavior gets changed
anotherMethodRunme.run();
}
}
May I also add that we can emulate Extensible enums using interfaces.
From Joshua Bloch's brilliant book
http://books.google.com/books?id=ka2VUBqHiWkC&pg=PA165&lpg=PA165&dq=mulate+extensible+enums+with+interfaces&source=bl&ots=yYKhIho1R0&sig=vd6xgrOcKr4Xhb6JDAdkxLO278A&hl=en&sa=X&ei=XyBgUqLVD8-v4APE6YGABg&ved=0CDAQ6AEwAQ#v=onepage&q=mulate%20extensible%20enums%20with%20interfaces&f=false
or
http://jtechies.blogspot.com/2012/07/item-34-emulate-extensible-enums-with.html
The whole point of an enum is to create a closed set of possible values. This makes it easier to reason about what a value of that enum type is so the set of constants would still remain closed and unextended, but then again the enum would carry the extra methods provided by the extending class.

Are java enum variables static? [duplicate]

This question already has answers here:
In Java, are enum types inside a class static?
(2 answers)
Closed 7 years ago.
public enum Operations {
SINGLE,
MULTIPLE;
private Type operation;
public void setOperation(Type operation) {
this.operation = operation;
}
public Type getOperation() {
return operation;
}
public static void main(String[] args) {
Operations oper1 = Operations.SINGLE;
oper1.setOperation(Type.GET);
Operations oper2 = Operations.SINGLE;
oper2.setOperation(Type.POST);
System.out.println(oper1.getOperation());
System.out.println(oper2.getOperation());
}
}
enum Type {
POST,
GET;
}
In the above code, the value of operation changes for both the Operations. How can I have two instances of Operations.SINGLE with different operation type?
Yes, instances are implicitly static and final. This means that the code is unwise. Imagine two threads both calling SINGLE.setOperation(Type); you will have no confidence in what you are calling.
From the Java Language Specification, Section 8.9:
Enum types (§8.9) must not be declared abstract; doing so will result in a compile-time error.
An enum type is implicitly final unless it contains at least one enum constant that has a class body.
It is a compile-time error to explicitly declare an enum type to be final.
Nested enum types are implicitly static. It is permissible to explicitly declare a nested enum type to be static.
And in the next section:
The body of an enum type may contain enum constants. An enum constant defines an instance of the enum type.
Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant.
How can I have two instances of Operations.SINGLE with different operation type?
The fundamental idea behind an enum is that there is one, and only one, instance of each of its members. This is what lets you safely compare them for equality, without fear that there's another SINGLE or MULTIPLE created in some other place.
If you want multiple instances of SINGLE, make it a class, not an enum. The fact that you made your enum mutable indirectly points in the same direction: using enum is a wrong choice in your situation.
Enum instances are "static" (ie behave like static variables), but are not immutable.
All threads see the same object referred to by the enum name - they are like singletons, with an iron-clad guarantee from the JVM that there is only ever one instance of an enum. Changing a field of an enum changes it for everyone.
It is good practice to make your fields final in an enum and to make them immutable.
I'm one year and a half too late. But I see the question was not really answered.
The solution would be using a class instead of enum, that has those two enums as its fields:
class Operation {
Quantity quantity;
Type type;
Operation(Quantity quantity, Type type) {
this.quantity = quantity;
this.type = type;
}
}
You can, of course, use enum instead of class. Then you'll have to enumerate all combinations:
enum Operation {
SINGLE_GET(Quantity.SINGLE, Type.GET)
SINGLE_POST(Quantity.SINGLE, Type.POST)
MULTIPLE_GET(Quantity.MULTIPLE, Type.GET)
// ... more options
// contents same as in class Operation, constructor private by default
}
Both approaches are valid, sometimes you really want to enumerate all the combinations, most of the time, however, you should probably stick with the class approach.
For brevity, I didn't define the enums Quantity and Type, they are just simple enums.
Yes, all elements of enum are static final constant.
However as mentioned in another answer by darijan, there is a logical mistake in your program.
There is an error in fourth line of main method
oper1.setOperation(Type.POST);
should be
oper2.setOperation(Type.POST);

Why can't I define a static method in a Java interface?

EDIT: As of Java 8, static methods are now allowed in interfaces.
Here's the example:
public interface IXMLizable<T>
{
static T newInstanceFromXML(Element e);
Element toXMLElement();
}
Of course this won't work. But why not?
One of the possible issues would be, what happens when you call:
IXMLizable.newInstanceFromXML(e);
In this case, I think it should just call an empty method (i.e. {}). All subclasses would be forced to implement the static method, so they'd all be fine when calling the static method. So why isn't this possible?
EDIT: I guess I'm looking for answer that's deeper than "because that's the way Java is".
Is there a particular technological reason why static methods can't be overwritten? That is, why did the designers of Java decide to make instance methods overrideable but not static methods?
EDIT: The problem with my design is I'm trying to use interfaces to enforce a coding convention.
That is, the goal of the interface is twofold:
I want the IXMLizable interface to allow me to convert classes that implement it to XML elements (using polymorphism, works fine).
If someone wants to make a new instance of a class that implements the IXMLizable interface, they will always know that there will be a newInstanceFromXML(Element e) static constructor.
Is there any other way to ensure this, other than just putting a comment in the interface?
Java 8 permits static interface methods
With Java 8, interfaces can have static methods. They can also have concrete instance methods, but not instance fields.
There are really two questions here:
Why, in the bad old days, couldn't interfaces contain static methods?
Why can't static methods be overridden?
Static methods in interfaces
There was no strong technical reason why interfaces couldn't have had static methods in previous versions. This is summed up nicely by the poster of a duplicate question. Static interface methods were initially considered as a small language change, and then there was an official proposal to add them in Java 7, but it was later dropped due to unforeseen complications.
Finally, Java 8 introduced static interface methods, as well as override-able instance methods with a default implementation. They still can't have instance fields though. These features are part of the lambda expression support, and you can read more about them in Part H of JSR 335.
Overriding static methods
The answer to the second question is a little more complicated.
Static methods are resolvable at compile time. Dynamic dispatch makes sense for instance methods, where the compiler can't determine the concrete type of the object, and, thus, can't resolve the method to invoke. But invoking a static method requires a class, and since that class is known statically—at compile time—dynamic dispatch is unnecessary.
A little background on how instance methods work is necessary to understand what's going on here. I'm sure the actual implementation is quite different, but let me explain my notion of method dispatch, which models observed behavior accurately.
Pretend that each class has a hash table that maps method signatures (name and parameter types) to an actual chunk of code to implement the method. When the virtual machine attempts to invoke a method on an instance, it queries the object for its class and looks up the requested signature in the class's table. If a method body is found, it is invoked. Otherwise, the parent class of the class is obtained, and the lookup is repeated there. This proceeds until the method is found, or there are no more parent classes—which results in a NoSuchMethodError.
If a superclass and a subclass both have an entry in their tables for the same method signature, the sub class's version is encountered first, and the superclass's version is never used—this is an "override".
Now, suppose we skip the object instance and just start with a subclass. The resolution could proceed as above, giving you a sort of "overridable" static method. The resolution can all happen at compile-time, however, since the compiler is starting from a known class, rather than waiting until runtime to query an object of an unspecified type for its class. There is no point in "overriding" a static method since one can always specify the class that contains the desired version.
Constructor "interfaces"
Here's a little more material to address the recent edit to the question.
It sounds like you want to effectively mandate a constructor-like method for each implementation of IXMLizable. Forget about trying to enforce this with an interface for a minute, and pretend that you have some classes that meet this requirement. How would you use it?
class Foo implements IXMLizable<Foo> {
public static Foo newInstanceFromXML(Element e) { ... }
}
Foo obj = Foo.newInstanceFromXML(e);
Since you have to explicitly name the concrete type Foo when "constructing" the new object, the compiler can verify that it does indeed have the necessary factory method. And if it doesn't, so what? If I can implement an IXMLizable that lacks the "constructor", and I create an instance and pass it to your code, it is an IXMLizable with all the necessary interface.
Construction is part of the implementation, not the interface. Any code that works successfully with the interface doesn't care about the constructor. Any code that cares about the constructor needs to know the concrete type anyway, and the interface can be ignored.
This was already asked and answered, here
To duplicate my answer:
There is never a point to declaring a static method in an interface. They cannot be executed by the normal call MyInterface.staticMethod(). If you call them by specifying the implementing class MyImplementor.staticMethod() then you must know the actual class, so it is irrelevant whether the interface contains it or not.
More importantly, static methods are never overridden, and if you try to do:
MyInterface var = new MyImplementingClass();
var.staticMethod();
the rules for static say that the method defined in the declared type of var must be executed. Since this is an interface, this is impossible.
The reason you can't execute "result=MyInterface.staticMethod()" is that it would have to execute the version of the method defined in MyInterface. But there can't be a version defined in MyInterface, because it's an interface. It doesn't have code by definition.
While you can say that this amounts to "because Java does it that way", in reality the decision is a logical consequence of other design decisions, also made for very good reason.
With the advent of Java 8 it is possible now to write default and static methods in interface.
docs.oracle/staticMethod
For example:
public interface Arithmetic {
public int add(int a, int b);
public static int multiply(int a, int b) {
return a * b;
}
}
public class ArithmaticImplementation implements Arithmetic {
#Override
public int add(int a, int b) {
return a + b;
}
public static void main(String[] args) {
int result = Arithmetic.multiply(2, 3);
System.out.println(result);
}
}
Result : 6
TIP : Calling an static interface method doesn't require to be implemented by any class. Surely, this happens because the same rules for static methods in superclasses applies for static methods on interfaces.
Normally this is done using a Factory pattern
public interface IXMLizableFactory<T extends IXMLizable> {
public T newInstanceFromXML(Element e);
}
public interface IXMLizable {
public Element toXMLElement();
}
Because static methods cannot be overridden in subclasses, and hence they cannot be abstract. And all methods in an interface are, de facto, abstract.
Why can't I define a static method in a Java interface?
Actually you can in Java 8.
As per Java doc:
A static method is a method that is associated with the class in which
it is defined rather than with any object. Every instance of the class
shares its static methods
In Java 8 an interface can have default methods and static methods. This makes it easier for us to organize helper methods in our libraries. We can keep static methods specific to an interface in the same interface rather than in a separate class.
Example of default method:
list.sort(ordering);
instead of
Collections.sort(list, ordering);
Example of static method (from doc itself):
public interface TimeClient {
// ...
static public ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +
"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default public ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
Interfaces are concerned with polymorphism which is inherently tied to object instances, not classes. Therefore static doesn't make sense in the context of an interface.
First, all language decisions are decisions made by the language creators. There is nothing in the world of software engineering or language defining or compiler / interpreter writing which says that a static method cannot be part of an interface. I've created a couple of languages and written compilers for them -- it's all just sitting down and defining meaningful semantics. I'd argue that the semantics of a static method in an interface are remarkably clear -- even if the compiler has to defer resolution of the method to run-time.
Secondly, that we use static methods at all means there is a valid reason for having an interface pattern which includes static methods -- I can't speak for any of you, but I use static methods on a regular basis.
The most likely correct answer is that there was no perceived need, at the time the language was defined, for static methods in interfaces. Java has grown a lot over the years and this is an item that has apparently gained some interest. That it was looked at for Java 7 indicates that its risen to a level of interest that might result in a language change. I, for one, will be happy when I no longer have to instantiate an object just so I can call my non-static getter method to access a static variable in a subclass instance ...
"Is there a particular reason that static methods cannot be overridden".
Let me re-word that question for your by filling in the definitions.
"Is there a particular reason that methods resolved at compile time cannot be resolved at runtime."
Or, to put in more completely, If I want to call a method without an instance, but knowing the class, how can I have it resolved based upon the instance that I don't have.
Static methods aren't virtual like instance methods so I suppose the Java designers decided they didn't want them in interfaces.
But you can put classes containing static methods inside interfaces. You could try that!
public interface Test {
static class Inner {
public static Object get() {
return 0;
}
}
}
Commenting EDIT: As of Java 8, static methods are now allowed in interfaces.
It is right, static methods since Java 8 are allowed in interfaces, but your example still won't work. You cannot just define a static method: you have to implement it or you will obtain a compilation error.
Several answers have discussed the problems with the concept of overridable static methods. However sometimes you come across a pattern where it seems like that's just what you want to use.
For example, I work with an object-relational layer that has value objects, but also has commands for manipulating the value objects. For various reasons, each value object class has to define some static methods that let the framework find the command instance. For example, to create a Person you'd do:
cmd = createCmd(Person.getCreateCmdId());
Person p = cmd.execute();
and to load a Person by ID you'd do
cmd = createCmd(Person.getGetCmdId());
cmd.set(ID, id);
Person p = cmd.execute();
This is fairly convenient, however it has its problems; notably the existence of the static methods can not be enforced in the interface. An overridable static method in the interface would be exactly what we'd need, if only it could work somehow.
EJBs solve this problem by having a Home interface; each object knows how to find its Home and the Home contains the "static" methods. This way the "static" methods can be overridden as needed, and you don't clutter up the normal (it's called "Remote") interface with methods that don't apply to an instance of your bean. Just make the normal interface specify a "getHome()" method. Return an instance of the Home object (which could be a singleton, I suppose) and the caller can perform operations that affect all Person objects.
Why can't I define a static method in a Java interface?
All methods in an interface are explicitly abstract and hence you cannot define them as static because static methods cannot be abstract.
Well, without generics, static interfaces are useless because all static method calls are resolved at compile time. So, there's no real use for them.
With generics, they have use -- with or without a default implementation. Obviously there would need to be overriding and so on. However, my guess is that such usage wasn't very OO (as the other answers point out obtusely) and hence wasn't considered worth the effort they'd require to implement usefully.
An interface can never be dereferenced statically, e.g. ISomething.member. An interface is always dereferenced via a variable that refers to an instance of a subclass of the interface. Thus, an interface reference can never know which subclass it refers to without an instance of its subclass.
Thus the closest approximation to a static method in an interface would be a non-static method that ignores "this", i.e. does not access any non-static members of the instance. At the low-level abstraction, every non-static method (after lookup in any vtable) is really just a function with class scope that takes "this" as an implicit formal parameter. See Scala's singleton object and interoperability with Java as evidence of that concept.
And thus every static method is a function with class scope that does not take a "this" parameter. Thus normally a static method can be called statically, but as previously stated, an interface has no implementation (is abstract).
Thus to get closest approximation to a static method in an interface, is to use a non-static method, then don't access any of the non-static instance members. There would be no possible performance benefit any other way, because there is no way to statically link (at compile-time) a ISomething.member(). The only benefit I see of a static method in an interface is that it would not input (i.e. ignore) an implicit "this" and thus disallow access to any of the non-static instance members. This would declare implicitly that the function that doesn't access "this", is immutate and not even readonly with respect to its containing class. But a declaration of "static" in an interface ISomething would also confuse people who tried to access it with ISomething.member() which would cause a compiler error. I suppose if the compiler error was sufficiently explanatory, it would be better than trying to educate people about using a non-static method to accomplish what they want (apparently mostly factory methods), as we are doing here (and has been repeated for 3 Q&A times on this site), so it is obviously an issue that is not intuitive for many people. I had to think about it for a while to get the correct understanding.
The way to get a mutable static field in an interface is use non-static getter and setter methods in an interface, to access that static field that in the subclass. Sidenote, apparently immutable statics can be declared in a Java interface with static final.
Interfaces just provide a list of things a class will provide, not an actual implementation of those things, which is what your static item is.
If you want statics, use an abstract class and inherit it, otherwise, remove the static.
Hope that helps!
You can't define static methods in an interface because static methods belongs to a class not to an instance of class, and interfaces are not Classes. Read more here.
However, If you want you can do this:
public class A {
public static void methodX() {
}
}
public class B extends A {
public static void methodX() {
}
}
In this case what you have is two classes with 2 distinct static methods called methodX().
Suppose you could do it; consider this example:
interface Iface {
public static void thisIsTheMethod();
}
class A implements Iface {
public static void thisIsTheMethod(){
system.out.print("I'm class A");
}
}
class B extends Class A {
public static void thisIsTheMethod(){
System.out.print("I'm class B");
}
}
SomeClass {
void doStuff(Iface face) {
IFace.thisIsTheMethod();
// now what would/could/should happen here.
}
}
Something that could be implemented is static interface (instead of static method in an interface). All classes implementing a given static interface should implement the corresponding static methods. You could get static interface SI from any Class clazz using
SI si = clazz.getStatic(SI.class); // null if clazz doesn't implement SI
// alternatively if the class is known at compile time
SI si = Someclass.static.SI; // either compiler errror or not null
then you can call si.method(params).
This would be useful (for factory design pattern for example) because you can get (or check the implementation of) SI static methods implementation from a compile time unknown class !
A dynamic dispatch is necessary and you can override the static methods (if not final) of a class by extending it (when called through the static interface).
Obviously, these methods can only access static variables of their class.
While I realize that Java 8 resolves this issue, I thought I'd chime in with a scenario I am currently working on (locked into using Java 7) where being able to specify static methods in an interface would be helpful.
I have several enum definitions where I've defined "id" and "displayName" fields along with helper methods evaluating the values for various reasons. Implementing an interface allows me to ensure that the getter methods are in place but not the static helper methods. Being an enum, there really isn't a clean way to offload the helper methods into an inherited abstract class or something of the like so the methods have to be defined in the enum itself. Also because it is an enum, you wouldn't ever be able to actually pass it as an instanced object and treat it as the interface type, but being able to require the existence of the static helper methods through an interface is what I like about it being supported in Java 8.
Here's code illustrating my point.
Interface definition:
public interface IGenericEnum <T extends Enum<T>> {
String getId();
String getDisplayName();
//If I was using Java 8 static helper methods would go here
}
Example of one enum definition:
public enum ExecutionModeType implements IGenericEnum<ExecutionModeType> {
STANDARD ("Standard", "Standard Mode"),
DEBUG ("Debug", "Debug Mode");
String id;
String displayName;
//Getter methods
public String getId() {
return id;
}
public String getDisplayName() {
return displayName;
}
//Constructor
private ExecutionModeType(String id, String displayName) {
this.id = id;
this.displayName = displayName;
}
//Helper methods - not enforced by Interface
public static boolean isValidId(String id) {
return GenericEnumUtility.isValidId(ExecutionModeType.class, id);
}
public static String printIdOptions(String delimiter){
return GenericEnumUtility.printIdOptions(ExecutionModeType.class, delimiter);
}
public static String[] getIdArray(){
return GenericEnumUtility.getIdArray(ExecutionModeType.class);
}
public static ExecutionModeType getById(String id) throws NoSuchObjectException {
return GenericEnumUtility.getById(ExecutionModeType.class, id);
}
}
Generic enum utility definition:
public class GenericEnumUtility {
public static <T extends Enum<T> & IGenericEnum<T>> boolean isValidId(Class<T> enumType, String id) {
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
if(enumOption.getId().equals(id)) {
return true;
}
}
return false;
}
public static <T extends Enum<T> & IGenericEnum<T>> String printIdOptions(Class<T> enumType, String delimiter){
String ret = "";
delimiter = delimiter == null ? " " : delimiter;
int i = 0;
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
if(i == 0) {
ret = enumOption.getId();
} else {
ret += delimiter + enumOption.getId();
}
i++;
}
return ret;
}
public static <T extends Enum<T> & IGenericEnum<T>> String[] getIdArray(Class<T> enumType){
List<String> idValues = new ArrayList<String>();
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
idValues.add(enumOption.getId());
}
return idValues.toArray(new String[idValues.size()]);
}
#SuppressWarnings("unchecked")
public static <T extends Enum<T> & IGenericEnum<T>> T getById(Class<T> enumType, String id) throws NoSuchObjectException {
id = id == null ? "" : id;
for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
if(id.equals(enumOption.getId())) {
return (T)enumOption;
}
}
throw new NoSuchObjectException(String.format("ERROR: \"%s\" is not a valid ID. Valid IDs are: %s.", id, printIdOptions(enumType, " , ")));
}
}
Let's suppose static methods were allowed in interfaces:
* They would force all implementing classes to declare that method.
* Interfaces would usually be used through objects, so the only effective methods on those would be the non-static ones.
* Any class which knows a particular interface could invoke its static methods. Hence a implementing class' static method would be called underneath, but the invoker class does not know which. How to know it? It has no instantiation to guess that!
Interfaces were thought to be used when working with objects. This way, an object is instantiated from a particular class, so this last matter is solved. The invoking class need not know which particular class is because the instantiation may be done by a third class. So the invoking class knows only the interface.
If we want this to be extended to static methods, we should have the possibility to especify an implementing class before, then pass a reference to the invoking class. This could use the class through the static methods in the interface. But what is the differente between this reference and an object? We just need an object representing what it was the class. Now, the object represents the old class, and could implement a new interface including the old static methods - those are now non-static.
Metaclasses serve for this purpose. You may try the class Class of Java. But the problem is that Java is not flexible enough for this. You can not declare a method in the class object of an interface.
This is a meta issue - when you need to do ass
..blah blah
anyway you have an easy workaround - making the method non-static with the same logic. But then you would have to first create an object to call the method.
To solve this :
error: missing method body, or declare abstract
static void main(String[] args);
interface I
{
int x=20;
void getValue();
static void main(String[] args){};//Put curly braces
}
class InterDemo implements I
{
public void getValue()
{
System.out.println(x);
}
public static void main(String[] args)
{
InterDemo i=new InterDemo();
i.getValue();
}
}
output :
20
Now we can use static method in interface
I think java does not have static interface methods because you do not need them. You may think you do, but...
How would you use them? If you want to call them like
MyImplClass.myMethod()
then you do not need to declare it in the interface. If you want to call them like
myInstance.myMethod()
then it should not be static.
If you are actually going to use first way, but just want to enforce each implementation to have such static method, then it is really a coding convention, not a contract between instance that implements an interface and calling code.
Interfaces allow you to define contract between instance of class that implement the interface and calling code. And java helps you to be sure that this contract is not violated, so you can rely on it and don't worry what class implements this contract, just "someone who signed a contract" is enough. In case of static interfaces your code
MyImplClass.myMethod()
does not rely on the fact that each interface implementation has this method, so you do not need java to help you to be sure with it.
What is the need of static method in interface, static methods are used basically when you don't have to create an instance of object whole idea of interface is to bring in OOP concepts with introduction of static method you're diverting from concept.

Categories

Resources