Ok, this may be a silly question but I have to know for sure... I have a class which I need to annotate with a custom annotation. Also, this class has to implement a custom interface. Now the question: is there any way I can just annotate the class and then use the annotation ALSO like an interface for example forcing a method implementation? I think that is not possible but maybe there's a way... Thank you.
Yes and no. You can eg. write an annotation processor which checks if a particular method has been implemented. At runtime you will have to check for the annotation and method using reflection if you're not implementing an interface. But this is acutually how most modern frameworks work these days (not forcing you to implement/ extend some specific interface/ class).
No, because annotations are used to describe some meta-info and they are not used by compiler to define class types (and java as you know is strongly typed language).
The main issue will be in the next case:
public interface Hello{
public void sayHello();
}
#Hello
public class HelloImpl{
...
}
public class HelloService{
public void perform (Hello hello) {}
}
So if your HelloImpl will not implement Hello interface, then in java there is no way to pass your HelloImpl in HelloService
Related
This is a question that has been bothering me for a while.
In frameworks like Jersey we have interface(s) that we can subclass to add some functionality to our program. for example to add request filtering in a RESt application we can implement ContainerRequestFilter then Voila we got authentication.
My question is how does the framework/library know that we have subclass one of its interfaces?
as per my understanding you can't instantiate an interface, only its subclass such as:
public interface Greeter{
void sayHi();
}
public class SpanishGreeter implements Greeter{
#override
void sayHi(){
System.out.println("Hola");
}
}
public class Controller{
public void main(String[] args){
//We must know the name of subclass to instantiate?
Greeter spanishG = new SpanishGreeter();
}
}
What you're looking for is classpath scanning.
This isn't a trivial task, and it's pretty much what the name says: you basically need to scan the classpath and load every class you find (although the typical implementation will allow you to limit your search to certain packages and its subpackages only, to stop from things going really crazy).
There are no special tricks in the Java language that would make this task easy.
The good news is that you don't need to write it from scratch, as frameworks like Spring already have it built in, or if you want to have complete low-level control, you can use a dedicated library like Reflections.
I think instanceof keyword helps in it.
System.out.println(spanishG instanceof Greeter); // true
That happens due to Polymorphism. The code you mentioned
Greeter spanishG = new SpanishGreeter();
That has reference of parent(in you case interface). On run time it checks weather there is a child class implementing the method if yes then it calls child class behaviour. And in your class you are instantiating with child class on run time JVM knows you have provided implementation.
I just begin to maintain a Java MVC project which use Java Guice Framework.
In almost the entire code, first developers passed as parameter an empty model interface extending another interface.
Here's the first Interface:
public interface FooModel extends ModelInterface {
}
And the other interface:
public interface ModelInterface {
public void addListener(FooListener fooListener);
void setFoo(boolean blop);
boolean isFoo();
}
That does not make any sense for me.
Is there a good reason/pattern use empty interface, in Java? Maybe for Guice?
Here is a good motivation for "marker interfaces". They are especially useful in aspect-oriented programming where they give you a point to attach to (and I guess Guice is just such a framework).
Only reason i know to use an empty interface would be as a marker interface. There are some examples like java.lang.Cloneable or Serializable.
It could be used to mark a class for a specific use.
Example: IRequiresSessionState
I have an abstract TemporalModel class (annotated with #MappedSuperclass) that adds created and updated fields to all extending models. I want to add a getLatest() static method to it:
public static TemporalModel getLatest() {
return find("order by created").first();
}
When I put this method on the base class, and call it through a concrete class (Transaction.getLatest()), I get an error:
UnsupportedOperationException occured : Please annotate your JPA model
with #javax.persistence.Entity annotation.
I suspect this is because JPA doesn't in fact know I'm calling this method "through" the base class (there is no real static method inheritance in Java).
Is there another way to implement this method once, instead of repeating it on all entity classes?
Update - one way to achieve this (which I'm using in another heavier app) is described here (gist). In my current app, however, I wouldn't like to use repositories, and I wondered if there's another, lighter solution.
Constructors and static methods can never be abstract. The idea behind an abstract class
is to create blueprints of methods, that have to get worked out in the subclass(es). I suggest trying an interface TemporalModel instead of an abstract class, in which you create the method public static TemporalModel getLatest();
I haven't used this Play framework, so I'm not sure about the details here, but usually, when one does the stuff you want to do, in Java, one simply specifies the concrete class as a parameter to the static method in question. It's kind of ugly, of course, but it is Java.
I assume that this find method is a static method that is added somehow (by annotation processing?) by this framework on every extending class, right? In that case, I think your only recourse is to do something like this:
public static <T extends TemporalModel> T getLatest(Class<T> cl) {
try {
/* I don't know what type the find() method returns, so you'll have to fix the casting */
return(cl.cast(cl.getMethod("find", String.class).invoke("order by created").first()));
} catch(AllThosePeskyReflectionExceptions e) {
throw(new Error(e));
}
}
I think that's the best way available given the premises. I know it's ugly, so I'd be happy to be wrong. :)
For Java programming, what are some benefits of using the #Deprecated notation on and interface method but not on the class that implements it?
public interface Joe {
#Deprecated
public void doSomething();
...
}
public final class Joseph implements Joe {
public void doSomething() {
...
}
...
}
#Deprecated is documentation. If people code to an interface you can mark certain aspects of that interface as deprecated. That way people know not to use it.
The implementation class of the interface is a detail. A method in that class happens to satisfy the interface but may not be deprecated on its own. Deprecating that method may or may not be appropriate.
Creating a new class that implements an interface means you need to implement the deprecated methods. They should probably work unless you know that the clients of the class don't use the deprecated methods. For example, if you are creating an HTTP servlet container you need to implement the HttpServletResponse.encodeUrl() method even though it's deprecated in favour of encodeURL(). That's because a user of your class may call that deprecated method.
I believe it's a shortcoming in the Java Language itself and it is nonsense to specify a method in an interface as deprecated via an annotation and not have the method considered deprecated in the implementing class.
It would be better if the #deprecated-ness of the method were inherited. Unfortunately, it seems Java does not support this.
Consider how tooling, such as an IDE, treats this situation: If the type of a variable is declared to be the interface, then #deprecated methods can be rendered with a strike through. But if the type of a variable is declared to be the implementing class and the class signature does not include #deprecated, then the method will be rendered without a strike through.
The fundamental question is: what does it MEAN for a method to be deprecated in an interface but not in an implementing class (or in an extending interface)? The only reasonable intention is for the method to be deprecated for everything below the interface in the class hierarchy. But the language does not support that behavior.
in my opinion it is controversial: a deprecated method interface should not not be used regardless it's implementation (please provide counterexamples if not)
If we want to refactor the existing code with inappropriate methods in the interface and in the implementation, then we can use #Deprecated in the interface methods in favor of clean new methods temporarily for few releases. It may be ugly, just to keep the code backward compatible we can make use of it. This will show in the IDE and SONAR report that its a deprecated method and forcing the clients to use new methods.
Let's say I have the following ruby code :
def use_object(object)
puts object.some_method
end
and , this will work on any object that responds to some_method,right?
Assuming that the following java interface exists :
interface TestInterface {
public String some_method();
}
Am I right to presume that interfaces are java's way to achieving the same thing ( with the only difference that the parameter's type would be TestInterface ) ?
You are right except that you can not define the body of a function in Java Interfaces, only prototypes.
Interfaces are the only way to implemente a pseudo multi-derivation in Java, since normal class derivation is only simple (just one parent).
No, interfaces in are not implemented. You can have multiple implementations of it though.
An interface would look more like:
interface TestInterface {
public String some_method();
}
And it could be implemented in a class:
public class TestClass implements TestInterface {
public String some_method() {
return "test";
}
}
And maybe more classes that implement this method differently. All classes that implement an interface have to implement the methods as declared by an interface.
With interfaces you can't achive exactly the same as in your Ruby example since Java is static typed.
Java interfaces define method signatures which an implementing class must provide. The JavaDoc explains all this in great detail.
In Java interfaces can only be used to declare methods, not the define (implement) them. Only classes can implement methods. But classes can implement interfaces. So you could for instance use the Adapter pattern to realize the same thing you did in ruby.
Yes, but only if you want to abstract out "anything having a some_method()" as a separate concept. If you only have one class that has some_method(), you need not specify an interface, and the parameter of use_object() will be that class.
Note also, that in Java we use camelCase instead of underscore_separated names.
It look like you are trying to program in Ruby using Java, you want want to rethink your approach to use more the idioms of the language.