So, I started using interfaces in Java a while ago. I have already created one, and I have a class, that implements that interface.
So this is the interface itself:
And this is the class that implements the Actor interface:
But, as you can see in the first picture, no methods are used, ecxept for create(). The most strange thing is that everything works absolutely fine! Only these underlined words freak me out a bit)
Your methods are never actually used. This is IntelliJ's way of highlighting dead code. Until you actually instantiate an Actor and call the method (see code sample below), it will appear as unused.
Actor actor = new Balls();
actor.createBody();
There is nothing wrong with these warnings: the IDE tells you that you could delete the underlined methods from the interface, because there is no code in your solution that would call these methods through the specific interface.
In top-down development, most interfaces start off looking like this: you start with an interface that has a lot of methods that nobody calls, and then the number of the unused methods goes down as you start using other operations from the interface. Eventually the number of unused methods goes down to zero, because your code starts making use of all interface methods that you define (or you delete the unused methods from your interface).
By default all methods in interface are abstract. That means they cannot have any definition. If everything runs and you have underlines, these are probably warnings. You can view more information by placing your cursor on underlined text (happens in Eclipse IDE). When you implement the interface you have to override all the methods present in interface, which you have done otherwise you would have got compile time error.
You have actually implemented/ used all methods of interface. Notice the curly brackets after method definitions in your class Balls. You just haven't written any code in them.
Read more about interfaces and you'll get a clearer picture.
Related
I am using simple strategy pattern for my project.
I need to add each concrete class of strategy interface in certain enum for later use.
for convenience reason, I am using a temporary interface which should be replaced later rather than implement every concrete classes to finish design first.
here is simple code that I tried.
public interface Strategy{
public void execute();
}
public interface NeedToImplement extends Strategy {
}
public enum strategyInfo {
A(ConcreteStrategyA.class, "blah blah" ),
B(ConcreteStrategyB.class, "blah~~" ),
C(NeedToImplement.class, "blah~~");
}
So far, code itself won't be a matter if I am the only person who manage this code and do not forget implementing every classes.
but this is team job, and I will split each of implementation for my team member so, if any of our team member forget implementing any class, It would cause disaster even in runtime.
I wanna make sure to be notified if NeedToImplement is exist as soon as I run a program by Exception or Error(like I can get a warning from #Deprecated )
while I can still compile without any compile error from code.
First idea come up in my mind was using custom annotation for NeedToImplement interface. but actually I am not sure about further details.
plz elaborate details if my idea is valid.
if not, any suggestion which is better than Ctrl+F will be appreciated as well.
What you could do would be to:
Mark your temporary interfaces with the #Depreceated tag in your JavaDoc. You could also provide information as to what/when developers should be using.
Another thing you could do to check for the existence of the interface, would be to wire up a simple unit test using something such as JUnit which would be run when your code compiles. Most compilation tools, such as ANT or Maven should allow you to attach test scripts at the end of compilation cycles. If the test fails, then, your temporary interface would be still there.
you could make new instances of each class in your execute() method, that I guess would be implemented for each action or similar in the project
you create an empty class for each class you will implement later and in each constructor you place a warning at your choice
While declaring a class as final , we cannot Inheritance this class , my question is why ? - from the java internals perspective.
I assume that the same principle apply to methods and instance as well.
is it somehow related to the class loader as well ? who is actually stopping me from override it?
There's nothing related to the JVM or internals (not really sure what exaclty you mean by that), it's a compile issue simply because you're breaking the rules.
If I think myself as a Java compiler, after parsing the tokens in your code I'm just going to look around for logical errors (semantic analysis) e.g. a circular inheritance scheme. The moment I see someone's attempt at extending a final class, I'm gonna go bazooka. That's it. No need to wake up the big bosses, the JVM or any other internals because the program cannot be correctly compiled in the first place.
If you want to know how the compiler works the way it does internally, think that while the compiler parses your code, it creates and fills some structures internal to itself for the purpose of error-checking and bytecode-translation. Also imagine in a simplified scenario that the final keyword attached to a class just sets a field in one of these structures attached to your class. After syntactic analysis, the compiler goes on with "logical" (semantic) analysis and checks (among other things) if some lunatic tries extending a final class. Even a brute search in an inheritance graph can pull that off. If a class is final and still has children, halt and notify the lunatic. The issue won't get more internal than the compiler.
It is nothing to do with Java internals.
The purpose of declaring a class to be final it to prevent it from being subclassed.
My question was what happening "underground" while declaring final ...
Well ... when a class is declared as final a flag is set in the class file to say this. If you then attempt to load a class that purports to be a subclass of a final class, the classloader will throw a VerifyError exception. The checks are done in the ClassLoader.defineClass(...) methods ... which are also final, so that normal programs can't interfere with them.
This aspect of classfile verification needs to be watertight for Java security reasons. If it wasn't then you could probably cause mayhem in a Java security sandbox by tricking trusted code into using (say) a mutable subtype of String.
The Java compiler also checks that you don't extend a final class, but you could subvert that by (for example) creating ".class" files by hand. Hence the need for load-time checks ...
Who is actually stopping me from override it?
Actually, it is the classloader. See above.
Let's look at it elementally, When you declare a variable as final, you did that because you don't want the value of that variable be changed for any reason afterwards, Right?.
Okay, under the assumption that you agree to that. The same principle is also applicable to classes.
Let's look at it this way: Why will you ever want to inherit a class? Probably because you want get access to the properties of the class and her behaviors (methods), Right? Once you have inherited these properties and behaviors you have the right the modify the accessible behavior to suite your precise need without having to re-implement all other behaviors. This is the value and power of in inheritance.
Hence, declaring a class as final implies that you don't want anyone to modify any behavior of the class. You tries to state that who so ever that will want use your class should use it as IS.
Therefore, any attempt to modify a final class is illogical and should be considered as error.
Eg.
Imaging if someone should be able to inherit your final Authentication class and modifying the actual authentication behavior (method). This should be a security bridge as it might compromise your reasons for setting the class as final.
Hence, it is a design practice.
I hope that make some sense?
One of the most useful features of Java 8 are the new default methods on interfaces. There are essentially two reasons (there may be others) why they have been introduced:
Providing actual default implementations. Example: Iterator.remove()
Allowing for JDK API evolution. Example: Iterable.forEach()
From an API designer's perspective, I would have liked to be able to use other modifiers on interface methods, e.g. final. This would be useful when adding convenience methods, preventing "accidental" overrides in implementing classes:
interface Sender {
// Convenience method to send an empty message
default final void send() {
send(null);
}
// Implementations should only implement this method
void send(String message);
}
The above is already common practice if Sender were a class:
abstract class Sender {
// Convenience method to send an empty message
final void send() {
send(null);
}
// Implementations should only implement this method
abstract void send(String message);
}
Now, default and final are obviously contradicting keywords, but the default keyword itself would not have been strictly required, so I'm assuming that this contradiction is deliberate, to reflect the subtle differences between "class methods with body" (just methods) and "interface methods with body" (default methods), i.e. differences which I have not yet understood.
At some point of time, support for modifiers like static and final on interface methods was not yet fully explored, citing Brian Goetz:
The other part is how far we're going to go to support class-building
tools in interfaces, such as final methods, private methods, protected
methods, static methods, etc. The answer is: we don't know yet
Since that time in late 2011, obviously, support for static methods in interfaces was added. Clearly, this added a lot of value to the JDK libraries themselves, such as with Comparator.comparing().
Question:
What is the reason final (and also static final) never made it to Java 8 interfaces?
This question is, to some degree, related to What is the reason why “synchronized” is not allowed in Java 8 interface methods?
The key thing to understand about default methods is that the primary design goal is interface evolution, not "turn interfaces into (mediocre) traits". While there's some overlap between the two, and we tried to be accommodating to the latter where it didn't get in the way of the former, these questions are best understood when viewed in this light. (Note too that class methods are going to be different from interface methods, no matter what the intent, by virtue of the fact that interface methods can be multiply inherited.)
The basic idea of a default method is: it is an interface method with a default implementation, and a derived class can provide a more specific implementation. And because the design center was interface evolution, it was a critical design goal that default methods be able to be added to interfaces after the fact in a source-compatible and binary-compatible manner.
The too-simple answer to "why not final default methods" is that then the body would then not simply be the default implementation, it would be the only implementation. While that's a little too simple an answer, it gives us a clue that the question is already heading in a questionable direction.
Another reason why final interface methods are questionable is that they create impossible problems for implementors. For example, suppose you have:
interface A {
default void foo() { ... }
}
interface B {
}
class C implements A, B {
}
Here, everything is good; C inherits foo() from A. Now supposing B is changed to have a foo method, with a default:
interface B {
default void foo() { ... }
}
Now, when we go to recompile C, the compiler will tell us that it doesn't know what behavior to inherit for foo(), so C has to override it (and could choose to delegate to A.super.foo() if it wanted to retain the same behavior.) But what if B had made its default final, and A is not under the control of the author of C? Now C is irretrievably broken; it can't compile without overriding foo(), but it can't override foo() if it was final in B.
This is just one example, but the point is that finality for methods is really a tool that makes more sense in the world of single-inheritance classes (generally which couple state to behavior), than to interfaces which merely contribute behavior and can be multiply inherited. It's too hard to reason about "what other interfaces might be mixed into the eventual implementor", and allowing an interface method to be final would likely cause these problems (and they would blow up not on the person who wrote the interface, but on the poor user who tries to implement it.)
Another reason to disallow them is that they wouldn't mean what you think they mean. A default implementation is only considered if the class (or its superclasses) don't provide a declaration (concrete or abstract) of the method. If a default method were final, but a superclass already implemented the method, the default would be ignored, which is probably not what the default author was expecting when declaring it final. (This inheritance behavior is a reflection of the design center for default methods -- interface evolution. It should be possible to add a default method (or a default implementation to an existing interface method) to existing interfaces that already have implementations, without changing the behavior of existing classes that implement the interface, guaranteeing that classes that already worked before default methods were added will work the same way in the presence of default methods.)
In the lambda mailing list there are plenty of discussions about it. One of those that seems to contain a lot of discussion about all that stuff is the following: On Varied interface method visibility (was Final defenders).
In this discussion, Talden, the author of the original question asks something very similar to your question:
The decision to make all interface members public was indeed an
unfortunate decision. That any use of interface in internal design
exposes implementation private details is a big one.
It's a tough one to fix without adding some obscure or compatibility
breaking nuances to the language. A compatibility break of that
magnitude and potential subtlety would seen unconscionable so a
solution has to exist that doesn't break existing code.
Could reintroducing the 'package' keyword as an access-specifier be
viable. It's absence of a specifier in an interface would imply
public-access and the absence of a specifier in a class implies
package-access. Which specifiers make sense in an interface is unclear
- especially if, to minimise the knowledge burden on developers, we have to ensure that access-specifiers mean the same thing in both
class and interface if they're present.
In the absence of default methods I'd have speculated that the
specifier of a member in an interface has to be at least as visible as
the interface itself (so the interface can actually be implemented in
all visible contexts) - with default methods that's not so certain.
Has there been any clear communication as to whether this is even a
possible in-scope discussion? If not, should it be held elsewhere.
Eventually Brian Goetz's answer was:
Yes, this is already being explored.
However, let me set some realistic expectations -- language / VM
features have a long lead time, even trivial-seeming ones like this.
The time for proposing new language feature ideas for Java SE 8 has
pretty much passed.
So, most likely it was never implemented because it was never part of the scope. It was never proposed in time to be considered.
In another heated discussion about final defender methods on the subject, Brian said again:
And you have gotten exactly what you wished for. That's exactly what
this feature adds -- multiple inheritance of behavior. Of course we
understand that people will use them as traits. And we've worked hard
to ensure that the the model of inheritance they offer is simple and
clean enough that people can get good results doing so in a broad
variety of situations. We have, at the same time, chosen not to push
them beyond the boundary of what works simply and cleanly, and that
leads to "aw, you didn't go far enough" reactions in some case. But
really, most of this thread seems to be grumbling that the glass is
merely 98% full. I'll take that 98% and get on with it!
So this reinforces my theory that it simply was not part of the scope or part of their design. What they did was to provide enough functionality to deal with the issues of API evolution.
It will be hard to find and identify "THE" answer, for the resons mentioned in the comments from #EJP : There are roughly 2 (+/- 2) people in the world who can give the definite answer at all. And in doubt, the answer might just be something like "Supporting final default methods did not seem to be worth the effort of restructuring the internal call resolution mechanisms". This is speculation, of course, but it is at least backed by subtle evidences, like this Statement (by one of the two persons) in the OpenJDK mailing list:
"I suppose if "final default" methods were allowed, they might need rewriting from internal invokespecial to user-visible invokeinterface."
and trivial facts like that a method is simply not considered to be a (really) final method when it is a default method, as currently implemented in the Method::is_final_method method in the OpenJDK.
Further really "authorative" information is indeed hard to find, even with excessive websearches and by reading commit logs. I thought that it might be related to potential ambiguities during the resolution of interface method calls with the invokeinterface instruction and and class method calls, corresponding to the invokevirtual instruction: For the invokevirtual instruction, there may be a simple vtable lookup, because the method must either be inherited from a superclass, or implemented by the class directly. In contrast to that, an invokeinterface call must examine the respective call site to find out which interface this call actually refers to (this is explained in more detail in the InterfaceCalls page of the HotSpot Wiki). However, final methods do either not get inserted into the vtable at all, or replace existing entries in the vtable (see klassVtable.cpp. Line 333), and similarly, default methods are replacing existing entries in the vtable (see klassVtable.cpp, Line 202). So the actual reason (and thus, the answer) must be hidden deeper inside the (rather complex) method call resolution mechanisms, but maybe these references will nevertheless be considered as being helpful, be it only for others that manage to derive the actual answer from that.
I wouldn't think it is neccessary to specify final on a convienience interface method, I can agree though that it may be helpful, but seemingly the costs have outweight the benefits.
What you are supposed to do, either way, is to write proper javadoc for the default method, showing exactly what the method is and is not allowed to do. In that way the classes implementing the interface "are not allowed" to change the implementation, though there are no guarantees.
Anyone could write a Collection that adheres to the interface and then does things in the methods that are absolutely counter intuitive, there is no way to shield yourself from that, other than writing extensive unit tests.
We add default keyword to our method inside an interface when we know that the class extending the interface may or may not override our implementation. But what if we want to add a method that we don't want any implementing class to override? Well, two options were available to us:
Add a default final method.
Add a static method.
Now, Java says that if we have a class implementing two or more interfaces such that they have a default method with exactly same method name and signature i.e. they are duplicate, then we need to provide an implementation of that method in our class. Now in case of default final methods, we can't provide an implementation and we are stuck. And that's why final keyword isn't used in interfaces.
Let's say you you have a class called Vehicle that outlines a protected (could also be abstract) method called speed. And, the sub class Car overrides that method to define its own implementation.
Now, assume that the need to have a speed method in the Vehicle class is no longer required (let's say all vehicles will be stationary for the whatever reason).
If I remove the method speed from Vehicle, I would like to throw a compile error so that so that the developer who has removed the method knows that sub class(es) are potentially relying on it to perform certain actions.
Technically speaking a compile error is not needed, but some sort of notification that acts as a hurdle when such re factoring is happening. Is there a programming pattern that can be employed to handle such a situation?
UPDATE: I am using Java 1.4 (Sorry!)
The #Override annotation is expressly for this purpose.
If you're not using Java 1.5+, then no, although you could use AOP to instrument those methods to throw an exception, or just use reflection and classpath scanning to go over all subclasses and check for the presence of said method.
If it's abstract, then there is no implementation that can be removed from the parent class, and your risk comes down to new subclasses not implementing it. If it's protected and defined in the parent, there are two cases that should already throw compiler errors if the parent implementation is removed.
1) A subclass calls that method without defining its own implementation. Method does not exist.
2) A subclass defines the method, but includes a call to super. Again, the method does not exist.
You can write super.speed() in nested classes and leave this method empty in parent. If you delete now this method in parent, you'll have an Exception. But there is a disadvantage - you must call it from all overrided methods. Try it, perhaps this will help you
Use #Override annotation for methods in subclases.
Once you remove the method from a base-class, tools like Eclipse and javac will issue a warining for those no-longer-overriding methods.
Edit: While you cannot use #Override before Java 1.5.0, there is a tool called xdoclet. Back in the days of J2EE and EJB 2.1 this was used to "simulate" annotations and do magical things with code based on javadoc-like markers. Look at it, maybe you can use it.
Edit 2: In Java 1.4.x, you can also use JavaDoc tag {#inheritDoc} for this kind of verification. Instead of annotating your method with #Override annotate it with #inheritDoc, like this:
public class MyAwesomeClass extends BaseClass
{
/** {#inheritDoc} */
protected void myAweSomeMethod()
{
//...
}
}
Now, if you change the myAweSomeMethod signature in BaseClass, or remove it, you will get warnings from JavaDoc tool, similar to this:
/home/npe/java-tests/MyAwesomeClass.java:4: warning - #inheritDoc used but myAwesomeMethod does not override or implement any method.
Hi I'm implementing a given design in java. Basically I have an abstract class which is called base and I have a number of concrete classes which are extending Base and implementing an interface from a different package. Each concrete class will be implementing a different interface. Now these interfaces contain both event-based and non event-based method signatures in them. My question here is; I'm only expected to implement non-event based methods in my concrete classes, however because of the implements keyword java forces me to insert an auto generated method body, which is basically return null. They might be implementing those event based methods later on but not at the moment. What would be an appropriate way to let the API user know that these methods do not contain an implementation. Here are my thoughts;
Use deprecated keyword
Create an exception class and throw that exception inside of the method and let the API user handle it.
I do not have the option of making changes to the existing architecture. Any idea really appreciated. Thank you.
According to Oracle, the reasons to deprecate an API include
It is insecure, buggy, or highly inefficient
It is going away in a future release
It encourages bad coding practices
neither of which actually fits your case.
Personally, I would favor throwing an UnsupportedOperationException which is already provided by the Standard Library in order to
indicate that the requested operation is not supported.
To me, this sounds more like what you actually want.
You can create your own interface which lists all the method you want users of your component to be able to access. Make this the only interface they use and additional public methods will not be visible.
Option (2) is good, but as you are following interfaces you'll want unchecked exceptions. And document the methods as unimplemented.
Deprecated implies a history, i.e., it works but should no longer be used. Since you are explicitly stating that the methods do not work, marking as deprecated will not prevent use nor indicate that the methods are unimplemented.
I would suggest use some mix bag of design patterns. That will help you solve this problem efficiently and make the code maintainable as well.
Based on my knowledge, you can use the Abstract Factory pattern here. See the design sketch below in the figure.
Method1 and method2 in subclass1 and subclass2 are the ones which are supposed to be exposed while method3 and method4 in subclass1 and subclass2 are the ones which we don't want to expose.
Create a Genericsubclass interface and create some methods in this interface depending upon the nature of methods you have in subclasses. For ex: i have create one method in this interface called nonEventbasedmethod1
Create a factory corresponding to every sub class and each factory will implement the GenericSubclass interface. Then implementation of nonEventbasedmethod1 method in subclass1Factory would be some thing like
nonEventbasedmethod1(){
subclass1.method1();
}
and implementation of nonEventbasedmethod1 method in subclass2Factory would be some thing like
nonEventbasedmethod1(){
subclass2.method3();
}
Then create a SubclassAbstract Factory which will return one of the subclass factories and then without worrying about which factory has been returned (that decision has already been taken in SubclassAbstractFactory before returning the appropriate factory) simply call the desired method from GenericSubclass interface and underneath one of the methods from the subclass1 or subclass2 will be invoked.
Hope this helps.
If you plain to throw an exception for "NotSupported" or "NotImplemented" Exception - consider the exception of NotImplementedException (at org.apache.commons).
However, I would reconsider to revisit your design and see if you can avoid having this - maybe you need to define another interface, which will hold the methods that are always implemented, and extend it in another interface (or provide an interface with no extension to the previous one) for the methods you not always implement.