Before, I used to declare a wrapper annotation by hand, with an array, and then call it like so:
#Foos({ #Foo(0), #Foo(1), #Foo(2) })
public void bar() {}
Since I was making an array with the { ... } initializers, it was more than clear that the order was to be the same of the declaration when I accessed this method later via Reflection.
However, when I use the new #Repeatable annotation from Java 8, do I have guarantee that the order will be kept?
I declared a simple set of annotations:
public #interface Foos {
Foo[] value();
}
#Repeatable(Foos.class)
public #interface Foo {
int value();
}
and run some tests with the most diverse scenarios:
#Foo(0) #Foo(1) #Foo(2)
public void bar1() {}
#Foo(2)
#Deprecated #Foo(5)
#Foo(10)
public void bar2() {}
and everything seems to work flawlessly (when accessing via Reflection), but I would not like to rely on undocumented stuff. It seems obvious to me that that should be the case, but I can't find it anywhere! Can anyone shed a light on this?
Here's what the Java Language Specification says:
If a declaration context or type context has multiple annotations of a repeatable annotation type T, then it is as if the context has no explicitly declared annotations of type T and one implicitly declared annotation of the containing annotation type of T.
The implicitly declared annotation is called the container annotation, and the multiple annotations of type T which appeared in the context are called the base annotations. The elements of the (array-typed) value element of the container annotation are all the base annotations in the left-to-right order in which they appeared in the context.
(emphasis mine)
So yes, the order of the annotations in the container annotation is the same as the order of declaration of the repeatable annotations.
Related
In introducing JPMS services, section 7.7.4 of the Java Language Specification notes that "The service type must be a class type, an interface type, or an annotation type."
I'm struggling to see the point of permitting an annotation. My understanding is that the JPMS notion of a service is something for which we expect to select an implementation at runtime. It also seems that, to be useful, the implementation needs at least the possibility of being something other than the original class that identifies the service being requested. But I believe an annotation cannot use "extends" so this could never happen? From that, I reach the belief that if I try to make a service out of an annotation type, I'd inevitably end up with a situation where the only thing that could ever be returned by a service lookup on, for example, SomeAnnotation.class would be exactly SomeAnnotation. That seems pointless, so I must assume I'm missing something.
Can anyone shed light on this, and perhaps offer examples of how an annotation might be a "service"?
It seems that you have missed another addition to the service providers. Within a named module, a service provider may return the implementation from a static method:
If the service provider declares a provider method, then the service loader invokes that method to obtain an instance of the service provider. A provider method is a public static method named "provider" with no formal parameters and a return type that is assignable to the service's interface or class.
In this case, the service provider itself need not be assignable to the service's interface or class.
from ServiceLoader
So the following would work:
module Example.Module {
uses example.Anno;
provides example.Anno with example.AnnoProvider;
}
package example;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
#Retention(RetentionPolicy.RUNTIME)
public #interface Anno {
int value();
}
package example;
#Anno(42)
public class AnnoProvider {
public static Anno provider() {
return AnnoProvider.class.getAnnotation(Anno.class);
}
}
package example;
import java.util.ServiceLoader;
public class ServiceUser {
public static void main(String[] args) {
for(Anno a: ServiceLoader.load(Anno.class)) {
System.out.println(a.value());
}
}
}
While in Java an annotation interface cannot explicitly extend any interfaces (but implicitly it always extends java.lang.annotation.Annotation), it can be implemented. I.e. it is syntactically possible to write a concrete class implementing an annotation interface, though according to JLS 9.6. Annotation Types such a class does not represent an annotation type:
a subclass or subinterface of an annotation type is never itself an
annotation type
Thus I believe that the original question boils down to "why would anyone want to explicitly implement an annotation interface?". This question has already been asked and answered on SO: Use cases for implementing annotations. The accepted answer there proposes to do this in order to partially overcome the limitation that a value of an annotation element must be either a constant expression, or a class literal, or an enum constant (see JLS 9.7.1. Normal Annotations): one may implement an annotation interface to "annotate" the implementing class with an "annotation" that includes dynamic data taken e.g. from a config file, a database, etc. Obviously, such a technique also requires small changes in the code that reads annotations, as the class implementing an annotation interface is not actually annotated, but instead its instance can be used as an instance of an annotation as if it was retrieved e.g. via java.lang.Class.getAnnotationsByType.
I know what it means in a comment for documentation purposes, but outside of that what does it mean? (I would normally just google this but every non letter symbol shows up in results)
The # symbol denotes a Java Annotation. What a Java annotation does, is that it adds a special attribute to the variable, method, class, interface, or other language elements. (This can be configured when you declare the annotation) When you add an annotation to something, other parts of the program can check whether something has an annotation or not. It then can use this information to do whatever stuff they need.
Let me give you some examples:
The #Override annotation
public class SuperClass {
public void someInterestingMethod() {
System.out.println("Superclass!");
}
}
public class DerivedClass extends SuperClass {
public void someInterestngMethod() {
System.out.println("Derived class!");
}
}
And when you do this:
SuperClass sc = new DerivedClass();
sc.someInterestingMethod();
The someInterestingMethod() call should be dynamically dispatched, and print "Derived class!", right? Well the derived class' method was actually misspelled, so DerivedClass got its own separate method called someInterestngMethod(), totally unrelated to the superclass' someInterestingMethod(). As such, someInterestingMethod() is no longer overridden, and the superclass' implementation is invoked.
The #Override keyword is intended to help with this. It signals your intent to the compiler, that you would like the annotated method to be an overload of one of the ancestor class' methods. If it's not (such as in this typo case, or if the SuperClass API changed and renamed the method), the will fail your compilation, to alert your attention to the broken override.
The #SuppressWarnings Annotation
Here is a method:
public void someMethod() {
int i;
}
There will be a compiler warning saying that i is never used. So you can add the #SuppressWarnings to the method to suppress the warning:
#SuppressWarnings("unused")
public void someMethod() {
int i;
}
Note that there is a parameter to the #SuppressWarnings annotation. Some annotations have parameters and you can look for the them in the javadoc. But for those that don't have parameters you don't need to add () like a method.
You can also declare your own annotations and use reflection to check for them. The above 2 annotations will be checked by the compiler.
The # sign is used to specify Java Annotation.
https://en.wikipedia.org/wiki/Java_annotation
There are built-in Java Annotation and user defined Custom Annotation.
Annotations are used in various ways, such as suppress warning, associate method to URI (Servlet), associate variables to resource (JNDI) etc
The # symbol is used for annotations. In my experience, the most common annotation is #Override, which indicates that a method is declared in a superclass. Other common annotations are #Deprecated, indicating that a method should no longer be used but still exists for backwards compatibility, and #SupressWarnings, to prevent warnings from showing up in the compiler.
Note that it's actually possible to get annotations which are not included in the core Java libraries and to declare your own annotations.
The # symbol denotes Annotations. They provide information about a class, its field or method (above which they appear). They cannot perform operations. The compilers or special annotation processors use this information to make writing code less verbose.
In Java Persistence API you use them to map a Java class with database tables.
For example
#Table()
Used to map the particular Java class to the date base table.
#Entity
Represents that the class is an entity class.
Similarly you can use many annotations to map individual columns, generate ids, generate version, relationships etc.
As some other suggests, it is Java's annotation. It helps the compiler to validate your code and to notify the programmer as well.
Very simple code example:
public class SomeClass {
#Override
public String toString() {
return "SomeClass";
}
#Deprecated
public void doSomeOperation() {
// some operation...
}
}
The annotation from SomeClass#toString which is #Override helps the compiler to determine that it is an overridden function from the implicit inheritance to the class Object.
While the annotation from SomeClass#doSomeOperation will warn the programmer that the function itself is deprecated already and should be avoided to use.
The annotations are for the reader or compiler, not executable code.
Here's an example of it in the JavaDoc of AnnotationLiteral e.g.
"An instance of an annotation type may be obtained by subclassing AnnotationLiteral."
public abstract class PayByQualifier extends AnnotationLiteral<PayBy> implements PayBy {
}
PayBy paybyCheque = new PayByQualifier() {
public PaymentMethod value() {
return CHEQUE;
}
};
There is a more complete example in Section 5.6.3 in the CDI spec.
5.6.3. Using AnnotationLiteral and TypeLiteral
javax.enterprise.util.AnnotationLiteral makes it easier to specify qualifiers when calling select():
#Qualifier
#Retention(RUNTIME)
#Target({METHOD, FIELD, PARAMETER, TYPE})
public #interface Synchronous {}
#Qualifier
#Retention(RUNTIME)
#Target({METHOD, FIELD, PARAMETER, TYPE})
public #interface PayBy {
PaymentMethod value();
#Nonbinding String comment() default "";
}
public PaymentProcessor getSynchronousPaymentProcessor(PaymentMethod paymentMethod) {
class SynchronousQualifier extends AnnotationLiteral<Synchronous>
implements Synchronous {}
class PayByQualifier extends AnnotationLiteral<PayBy>
implements PayBy {
public PaymentMethod value() { return paymentMethod; }
}
return anyPaymentProcessor.select(new SynchronousQualifier(), new PayByQualifier()).get();
}
And finally according to section 9.6 of the Java annotation types spec.:
Unless explicitly modified herein, all of the rules that apply to normal interface declarations apply to annotation type declarations.
For example, annotation types share the same namespace as normal class and interface types; and annotation type declarations are legal wherever interface declarations are legal, and have the same scope and accessibility.
However, the Java compiler complains when I attempt to implement an annotation. In particular, Intellij warns:
"Reports any classes declared as implementing or extending an annotation interface. While it is legal to extend an annotation interfaces, IT IS NEARLY MEANINGLESS, AND DISCOURAGED." (emphasis mine).
Here is the error message as displayed from within Intellij:
The Intellij warning seems to contradict the official Java documentation. I presume the Intellij warning is based upon a warning that comes from the Java compiler. What is correct? The Intellij and/or compiler warning or the documentation?
Annotations types are used as meta data. The typical use case for annotations, at runtime, is with reflection. You annotate something, then you use reflection to retrieve the annotation, process it, and possibly enhance the target. The annotation instances are created and given to you by the JVM through calls to the reflection API.
In that regard, creating your own annotation type instances, which AnnotationLiteral makes easier to do, is kind of pointless since you have no target, since nothing was actually annotated.
It can be useful for cases where you need to mock an annotation type instance or you want to inject some functionality that only exists when processing annotations.
Intellij is simply warning you that it's uncommon.
From Intellij support:
"We can change warning text for example to: "While it is legal to extend an annotation interface it is often done by accident, and the result won't be usable as an annotation." Note that you can always suppress the warning for the statement."
My response:
The proposed solution... would require developers to always suppress the warning for the statement. This solution is poor because the code would be littered with #SuppressWarning or, worse, the developer would need to turn off the warning altogether. The best and most useful solution, would be to not display any warning whatsoever if the developer extends AnnotationLiteral or TypeLiteral and implements an #interface at the same time.
A YouTrack Issue was filed.
Consider this #PointCut which gets triggered if a method is annotated with an #Secure annotation:
#Pointcut("execution(#Secure * *(..)) && #annotation(secure)")
public void accessOperation(final Access access) { }
This works perfectly well for methods like:
class Foo {
#Secure
public void secureMethod() { }
}
But is it possible to have a Pointcut which also gets triggered when the annotation only exists in a superclass/interface like this?
interface Foo {
#Secure
public void secureMethod();
}
class SubFoo implements Foo {
#Override
public void secureMethod() { // <--- execution of this method should be caught
/* .... */
}
}
EDIT:
This seems to be very closely related to: #AspectJ pointcut for subclasses of a class with an annotation
The only difference is that they use a class-level annotation, whereas I need a method-level annotation.
I don't know how AspectJ deals with annotations in such a scenario, but if he only checks the implementing class for a certain annotation, and that annotation is only found on the interface that the class implements, Java will report that infact that annoation is not present on the class method. You should annotate your annotation with #Inherited:
http://download.oracle.com/javase/6/docs/api/java/lang/annotation/Inherited.html
maybe this will do the trick (though in this case you should make sure that your Advice is not called multiple times).
I don't actually know the classes in my aspect
Considering what you are saying and the fact that #Inherited cannot be used on anything else but classes, you are implicitly hoping that AspectJ will do the job of finding out whether a method (or its overriden implementations and declarations) is annotated. This is much more than what is announced by AspectJ.
If your final objective is to secure some code, then all methods which should be secured should be properly annotated in the first place. So, the answer to your question is no, this is not possible in this context, especially if you know nothing about the classes.
However, there might be a workaround if you have access to an annotation processor. In this case, you could pick all #Secure annotation and work your way through the code with reflection to generate AspectJ code at compile time that would captures all method instances properly. Not easy, but possible.
Suppose I had an interface with some annotation(s), for example:
#SpecialClass
public interface IFoo { /* ... */ }
And suppose I make a class that implements the interface:
public class Foo implements IFoo { /* ... */ }
Is it possible for class Foo to somehow "inherit" or automatically copy all or some of the annotations from IFoo and its members (e.g. automagically annotate Foo as #SpecialClass, etc.)?
This would be convenient for implementing web service classes (e.g. those generated by the JAX-WS "wsimport" tool) by just implementing their annotated interfaces without explicitly having to copy the interface annotations to the implementing class (e.g. javax.jws.WebService, javax.xml.ws.RequestWrapper, etc).
EDIT: I'm leaving this answer here for general information and future readers, but Andreas pointed out an important bit of the Javadoc which I'd missed:
Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.
In other words, it wouldn't help in this situation. Also it's only useful if you have control over the annotation itself, of course.
I suspect the real answer is that you simply have to apply the annotation everywhere. If you're worried about forgetting one, you might want to write a unit test which finds all your classes (easier said than done, I realise) and checks that the annotation is present for all classes implementing the given interface.
Have you tried applying the Inherited annotation to the SpecialClass annotation itself?
Indicates that an annotation type is automatically inherited. If an Inherited meta-annotation is present on an annotation type declaration, and the user queries the annotation type on a class declaration, and the class declaration has no annotation for this type, then the class's superclass will automatically be queried for the annotation type. This process will be repeated until an annotation for this type is found, or the top of the class hierarchy (Object) is reached. If no superclass has an annotation for this type, then the query will indicate that the class in question has no such annotation.
That certainly sounds like exactly what you want.