I used JD to decompile a .jar executable file. I encountered an abstract enum code which does not compile:
private static abstract enum Type {
ANONYMOUS(4) , STANDARD(0);
private final int start;
private Type(int start) {
this.start = start;
}
public int getStart() {
return this.start;
}
public abstract void insertHeader(Sheet paramSheet,
SummaryCodec.Style paramStyle, float paramFloat1,
float paramFloat2);
public abstract String insertCommentSource(String paramString);
public abstract int insertBreakdown(Sheet paramSheet,
SummaryCodec.Style paramStyle, String paramString,
Entry paramEntry, int paramInt);
public abstract void collateComment(List<String> paramList,
String paramString);
}
Compiler errors:
Illegal modifier for the member enum Type; only public, protected, private & static are permitted
The enum constant ANONYMOUS must implement the abstract method collateComment(List, String)
The enum constant STANDARD must implement the abstract method collateComment(List, String)
Where can I find the code for the implementations of the abstract methods for ANONYMOUS, and STANDARD? I can't find it in the same file. Tried looking for it in other files.
JD apparently has a bug decompiling enums with abstract methods; you shouldn't get that class signature (which does correspond to the bytecode but doesn't take into account the magic the Java compiler does with enum).
Each enum instance that overrides a method declared gets its own .class file, just as anonymous classes do. Look for files named like Type$1.class in the same directory as Type.class.
Making an abstract enum does not make sense as you will definitely have instances.
In fact ANONYMOUS and STANDARD are instances of the enum Type which also why the compiler tells you that you have to implement the abstract method insertCommentSource.
I have no idea why the decompiler produced this code but i am very sure that this does not conform to Java language specifications! Also it does not make sense ;)
Related
Private interface methods are supported by Java 9.
This support allows non-abstract methods of an interface to share code between them. Private methods can be static or instance.
Can private methods of an interface be abstract or default?
May I ask for an example where "private static interface methods" are useful in terms of code?
No, the private methods in the interfaces are supposedly designed for clubbing in a piece of code that is internal to the interface implementation. Since these pertain to the implementation(consist of a body) and not the declaration it can neither be default and nor abstract when defined.
A private method is a static method or a non-default instance method that's declared with the private keyword. You cannot declare a default method to also be private because default methods are intended to be callable from the classes that implement their declaring interfaces.
The private static methods are useful in abstracting a common piece of code from static methods of an interface while defining its implementation.
Example of a private static method in an interface could be as follows. Consider an object, Question.java on StackOverflow defined as:
class Question {
int votes;
long created;
}
and an interface that proposes the sort by functionality as seen in the listed questions on StackOverflowTag :
public interface StackOverflowTag {
static List<Question> sortByNewest(List<Question> questions) {
return sortBy("NEWEST", questions);
}
static List<Question> sortByVotes(List<Question> questions) {
return sortBy("VOTE", questions);
}
//... other sortBy methods
private static List<Question> sortBy(String sortByType, List<Question> questions) {
if (sortByType.equals("VOTE")) {
// sort by votes
}
if (sortByType.equals("NEWEST")) {
// sort using the created timestamp
}
return questions;
}
}
Here the private static method sortBy of the interface internally implements the sorting based on the sortOrderType sharing the implementation with two public static methods of the interface which can be further consumed by a StackOverflowTagConsumer can simply access these interface static methods as :
public class StackOverFlowTagConsumer {
public static void main(String[] args) {
List<Question> currentQuestions = new ArrayList<>();
// if some action to sort by votes
displaySortedByVotes(currentQuestions);
// if another action to sort by newest
displaySortedByNewest(currentQuestions);
}
private static void displaySortedByVotes(List<Question> currentQuestions) {
System.out.println(StackOverflowTag.sortByVotes(currentQuestions));
}
private static void displaySortedByNewest(List<Question> currentQuestions) {
System.out.println(StackOverflowTag.sortByNewest(currentQuestions));
}
}
The default keyword for interface methods exist, because for interface methods, abstract is implicitly assumed if no other modifier contradicts it. Before Java 8, this applied to all interface methods, which were always considered abstract.
Since the presence of either, static or private, already implies that it cannot be abstract (which applies to ordinary classes as well), there is no need to add a default modifier and consequently, Java rules out this combination. And there is no point in asking for this combination either, as default merely implies that the method is not abstract, technically, so adding it to a method which is already not abstract wouldn’t change anything.
On the other hand, since the only methods needing a default keyword for declaring that they are not abstract, are public instance methods, the default keyword only applies to overridable methods, which conveniently matches the literal meaning of the word “default”.
private methods are useful to provide common operations for the public non-abstract methods of an interface when these common operations are not supposed to be called from the outside of the interface directly, much like private methods in ordinary classes, further, they exist in Java 8 already on the byte code level, as default and static methods may contain lambda expressions which are compiled into synthetic private methods, so there was no technical reason to deny that feature to the Java programming language.
No, these three combinations are mutually exclusive. Interface methods cannot be at the same time:
Default and abstract (because default means the opposite of abstract)
Default and private (because you cannot override a private method)
Abstract and private (because you cannot override a private method)
I know that an enum
enum Year
{
First, Second, Third, Fourth;
}
gets converted into
final class Year extends Enum<Year>
{
public static final Year First = new Year();
public static final Year Second = new Year();
public static final Year Third = new Year();
public static final Year Fourth = new Year();
}
When I tried to instantiate enum (not class) I got compile time error as:
error: enum types may not be instantiated
Year y = new Year();
As per my knowledge a private constructor makes a class non instantiable. And I thought that compiler is providing a private constructor. But again I got confused when saw we can define a constructor for enum with default modifier and still cannot create an object of type enum.
enum Year
{
First, Second, Third, Fourth;
Year()
{
}
}
class Example
{
public static void main(String[] args)
{
Year y = new Year();
}
}
My doubt is, if it is not about constructors then what makes enum in Java non instantiable?
It is specified in the Java Language Specification:
8.9. Enum Types
...
An enum type has no instances other than those defined by its enum constants. It is a compile-time error to attempt to explicitly instantiate an enum type (§15.9.1).
Hence the compiler ensures that this requirement is met. Since the compiler "knows" that the type is an enum, it can distinguish between enum Year and final class Year.
Also, no access modifier is allowed for an enum constructor:
8.9.2. Enum Body Declarations
...
It is a compile-time error if a constructor declaration in an enum declaration is public or protected.
...
In an enum declaration, a constructor declaration with no access modifiers is private.
So, in practice, an enum constructor looks like package-scoped (no access modifier), but it really is private.
Finally, the same section also states
In an enum declaration with no constructor declarations, a default constructor is implicitly declared. The default constructor is private, has no formal parameters, and has no throws clause.
This makes the enum non-instantiable even if no constructor is explicitly declared.
An enum in java has a default constructor when it's is not defined and it's private.
Default access modifier has different meanings in different scopes. For example inside a class default access modifier for methods and fields is package private.
Where as in an interface default access modifier means public. In fact there can be no other modifier on an interface field so it's implicitly public.
On a top level class it's package private (where only 2 access modifiers are allowed public and default package private)
So the answer to your question is it is so because compiler decides so. Compiler writer had to uphold the language specification contract.
You're right in thinking that it's a normal class after everything. Every object blueprint type in java is a class which can be represented by java.lang.Class. These restrictions for interfaces, enums, abstract classes, anonymous classes, method local classes are validated by compiler only.
If you can somehow escape the compiler and generate your own byte code for enums or other way around if you can modify the byte code of generated enum class so that it's private constructor becomes public may be you would be able to call it's constructor outside the enum's private scope. You can also try experimenting with reflection to do the same. In fact by generating byte code manually JVM languages like Groovy, Jython, JRuby, Clojure are able to provide functionalities that are not in Java itself. They're bypassing java compiler.
Purpose for having constructor in enums is to be able to set fields of constants in one call. All constants inside an enum are instances of the enum class, so they also consist the fields declared in it.
enum Test
{
T1(1), // equivalent to public static final Test T1 = new Test(1);
T2(2); // equivalent to public static final Test T2 = new Test(2);
int id;
Test(int id)
{
this.id = id;
}
}
And finally bellow is the output of decompiled code for above enum by using java -p Test.class
final class Test extends java.lang.Enum<Test>
{
public static final Test T1;
public static final Test T2;
int id;
private static final Test[] $VALUES;
public static Test[] values();
public static Test valueOf(java.lang.String);
private Test(int);
static {};
}
It should give a better understanding of what happens when the class compiles.
Can have an abstract class implementing all of its methods-- with no abstract methods in it.
Eg.:
public abstract class someClass {
int a;
public someClass (int a) { this.a = a; }
public void m1 () { /* do something */ }
private void m2 () { /* do something else */ }
}
What's the advantage, if any, of having such an abstract class compared to having the same class as a concrete one instead?
One i can think of is that, when i declare it as abstract, it won't be instantiated.
however, i can have the same effect by making it concrete and its constructor(s) private.
TIA.
//==================
EDIT: One other use I can think of:
it may be extending another abstract class or implementing an interface without implementing that class's abstract methods-- although it is implementing all methods of its own. for whatever it' worth.
It has a conceptual meaning: this class has a behaviour which makes no sense on its own.
Granted, it's difficult to imagine such a scenario without well-defined extension points (i.e. abstract methods), but occasionally it will be a reasonably accurate model of your problem.
You can have something like this:
public abstract class ObjectWithId {
private final String id;
public ObjectWithId( String id ) {
this.id = id;
}
public final String getId() {
return id;
}
}
And then you can extend it to declare different types of objects that have ids. Here you have a fully specified and implemented behaviour but no restriction on any other behaviours subclasses may exhibit.
Note though that a much neater way to model the same thing is to use composition instead of inheritance.
public final class ObjectWithId<T> {
private final String id;
private final T ob;
public ObjectWithId( String id, T ob ) {
this.id = id;
this.ob = ob;
}
public String getId() {
return id;
}
public T getObject() {
return ob;
}
}
But before generics were introduced (up to Java version 1.4), this wouldn't have been as elegant and obviously better than the abstract class solution because you'd have had to trade in type safety.
you can declare to implement an interface and don't provide implementation and then each child implicitly gets interface extended
you prevent to create instance of this class
you in future provide common implementation to all children
As you pointed out, you can prevent the class from being instantiated by making it's constructor private. Othere than that, there is no benefit whatsoever. This is probably supported just to provide language completeness.
We generally use Abstraction concept with inheritance
Consider using abstract classes if any of these statements apply to
your situation:
You want to share code among several closely related classes.
To answer your question,
Why declare a class with concrete methods Abstract?
One possible reason is to support inheritance without actually creating objects
Assume you have two classes one Abstract and other Concrete
Abstract class : AbsClass
abstract class AbsClass {
int a = 5;
//Constructor
public AbsClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
and
Concrete class : ConcreteClass
class ConcreteClass {
int a = 10;
//Made the constructor Private to prevent from creating objects of this class
private ConcreteClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
The above two classes should function similarly (?) Until you try to Subclass them
class AbsImplementer extends AbsClass {
//Works fine
}
class ConcImplementer extends ConcreteClass {
//Compilation Error Implicit super constructor ConcreteClass() is not visible
}
The practical difference is that you can't create an instance of it. You would have to subclass it and create an instance of the subclass.
As to WHY you would want to do this, in practice ... I'm hard pressed to think of a good reason. You could say that the class is only meaningful if someone creates a subclass that implements some function. But then why not make that function abstract in the super-class?
I wouldn't rule out the possibility that someone might come up with some example where this makes sense, but I can't think of one. Just because it's possible to write a piece of code and that code compiles successfully doesn't mean that that it makes sense. I mean, I can write "total_price = item_price * zip_code + customer_height_in_cubits - 7.879", but that doesn't mean such a line of code would be meaningful.
Well assume that you don't care whether the methods of the abstract class are implemented or abstract, but by design it has to be abstract so that when someone extends it, they have to add more methods or override the existing ones or use as is. If they don't want to override the methods then the default behavior is already provided in that abstract class.
In this abstract class, the only criteria you enforce is - one simply cannot instantiate that class and they have to have their only version of class before using it.
So in general, abstract class with few or all methods being implemented, is much better than having an interface which has no methods implemented at all. This is based on the assumption that you are using it as a single inheritance.
Consider something similar to the NVI pattern (not sure what you'd call it in Java):
public abstract class A {
public final void doSomething() {
System.out.println("required");
doOptional();
}
protected void doOptional() {
System.out.println("optional");
}
}
public class B extends A {
#Override
protected void doOptional() {
System.out.println("overridden");
}
}
For your public API, you only expose a public final method which cannot be overridden. It performs some required work inside there and an optional method. When extending this class, you can only override doOptional().
Calling B.doSomething() will always print "required" before it proceeds.
Since doOptional() is not abstract, there's no purely code reason that class A needs to be abstract. But it might be desired for your particular project. For example, a base service that is always extended into specific sub-projects.
This can be useful for cases when the classes derived from the abstract base class must have some behaviour that is different from each other but that behaviour can not be abstracted as residing within a method that has the same signature for all the classes. Being unable to share a signature can occur if the different behaviour requires methods that are passed different primitive types. Because they use primitive types you can not use generics to express the similarity.
An abstract base class without any abstract methods is acting a bit like a marker interface, in that it is declaring that implementing classes must provide some behaviour without having that behaviour encapsulated within a new method with a signature that is the same for all implementations. You would use an abstract base class rather than a marker interface when the implementing classes have some behaviour in common, especially if the base class can implement it for the derived classes.
For example:
abstract class Sender {
protected final void beginMessage() {
...
}
protected final void endMessage() {
...
}
protected final void appendToMessage(int x) {
...
}
}
final class LongSender extends Sender {
public void send(int a, int b, int c) {
beginMessage();
appendToMessage(a);
appendToMessage(b);
appendToMessage(c);
endMessage();
}
}
final class ShortSender extends Sender {
public void send(int a) {
beginMessage();
appendToMessage(a);
endMessage();
}
}
It can be useful if you consider it an utility class.
So I've run across something interesting which is incredibly useful. In an enum you can define an abstract method which each of the enum values is forced to provide an implementation for. For example, the following:
public enum Test {
RAWR ("Burninating the country side") {
#Override
public int doStuff() {
return 0;
}
};
private final String enumStuff;
private Test(String enumStuff) {
this.enumStuff = enumStuff;
}
public abstract int doStuff();
}
I added the private variable so you could see how it works in relation to the standard private constructor.
So this makes me wonder: what is RAWR actually, in relation to the Test class? Normally, this kind of syntax would make me think that I'm defining an anonymous inner class, but that doesn't seem intuitive here, since RAWR is anything but anonymous.
The closest thing I can think of is that the values of an enum are in fact extensions of the enum itself, e.g.,
public class RAWR extends Test {
#Override
public int doStuff() {
return 0;
}
}
So, does anyone know what's really going on with this?
From the JLS
An enum declaration specifies a new enum type, a special kind of class type.
[...]
The optional class body of an enum constant implicitly defines an
anonymous class declaration (§15.9.5) that extends the immediately
enclosing enum type.
The JLS also states
For each enum constant c declared in the body of the declaration of E,
E has an implicitly declared public static final field of type E that
has the same name as c. The field has a variable initializer
consisting of c, and is annotated by the same annotations as c.
The enum type you declare is Test. Every enum constant you declare is an instance of a subclass of Test, if it has a body.
Note that enum types are also implicitly final (you wouldn't be able to subclass them). The Java Language only allows this subclassing behavior for enum constants.
This is a very powerful feature of enums, in that not only is each enum a fully fledged class that can have constructors, setters, getters etc but each individual member of the enum can have its own anonymous implementation of the main enum class.
You actually are defining anonymous inner classes. Execute javap -c <classFile> on the class file of your enum to see how the enum looks when compiled.
You will see that an enum is nothing more than a normal class with public static final variables of the same type as the enum. You will also see that for each variable an anonymous inner class is assigned.
Example:
$ javap-c StatusCode.class
public final class de.haufe.StatusCode extends java.lang.Enum<de.haufe.StatusC ode> {
public static final de.haufe.StatusCode CREATED;
public static final de.haufe.StatusCode BAD_REQUEST;
public static final de.haufe.StatusCode UNAUTHORIZED;
public static final de.haufe.StatusCode NOT_FOUND;
public static final de.haufe.StatusCode PRECONDITION_FAILED;
public static final de.haufe.StatusCode UNSUPPORTED_MEDIA_TYPE;
public static final de.haufe.StatusCode UNPROCESSABLE_ENTITY;
public static final de.haufe.StatusCode LOCKED;
public static final de.haufe.StatusCode INTERNAL_SERVER_ERROR;
public static de.haufe.StatusCode[] values();
}
// more stuff
So this is not the best example because none of the enum value implements a method but you may get an idea what an enum actually is.
If you've ever used enums in generics you will have come across E extends Enum<E> which is the right way of defining the type of an enum. It's a little weird but once you get your head around it you can see that it is saying that an enum actually extends an Enum (note the different case) of itself. So essentially yes, all enums in the group seem to extend the base declaring class but the base declaring class is actually an Enum - sort of.
BTW - You can also make enums implement an interface:
interface Something {
int getValue();
}
enum It implements Something {
One,
Two,
Three;
#Override
public int getValue() {
return ordinal();
}
}
I was reading my old SCJP 6 book(author Kathy Sierra,Bert Bates) mentioned
All the interface methods are implicitly public and abstract by default
interface methods must not be static
For example, if we declare
interface Car
{
void bounce(); //no need of public abstract
void setBounceFactor(int b); //no need of public abstract
}
What the compiler sees
interface Car
{
public abstract void bounce();
public abstract void setBounceFactor(int b);
}
But from Java 8, interfaces can now define static methods. see this article everything-about-java-8
My question, what is the implicit declaration of interface methods in Java 8? Only public or nothing?
The rules for implicit modifiers do not change. Implicit modifiers are used when no other modifiers are specified. abstract is implied when neither static nor default has been specified. And all methods are always public whether implicit or explicit. Note that interface fields were always implicitly public static. This doesn’t change too.
But for the final words we should wait for the completion of Java 8.
Afaik it is something you can add and is added without changes to implementing classes.
For example. The List class will have a sort() method added. A sub class could have this method already but if every class needed this method it would break a lot of code and make having a default a bit useless.
I believe it is expected that the default method will be simple and call a static method or helper class to leave the interface uncluttered.
in short, default methods are public but not abstract.
btw interfaces have a method for static field initialisation.
what is the implicit declaration of interface methods in Java 8? Only
public or nothing?
Answer is: It is still public. private or protected are restricted. Look at following two examples
public interface A {
static void foo() {// Its ok. public will implicitly call.
System.out.println("A.foo");
}
private static void foo2() {// Compile time error
System.out.println("A.foo2");
}
}