Are annotations serializable by default? - java

Since I'm working with a framework that uses the Serializable interface in like every class, I want to make sure that the annotation interfaces in the project I'm working for are serializable as well. However, I can't neither implement nor extend Serializable in any #interface java file. This is why I'm wondering if these files are serializable by default (like enums for example) and if not, if there is a way to implement it in these files. (Even if it isn't an elegant way to code. Just want to know if it's possible in the first place). It's hard to find out where the NotSerializableExceptions come from, since the project has many fields that are not serializable (Lamdas etc.)
The Annotations are mostly structured like this in my case:
#Documented
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.ANNOTATION_TYPE)
public #interface RandomAnnotation {
//random code
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
#interface RandomA {
// no value
}
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
#interface RandomB {
// no value
}
}

Related

Is using a class as a field in an annoation bad memory management?

I have some design problems with an existing application. It can use annotations with a class field. As in the examples below. Are these fields going to cause to the class loader to stay in memory and create a leak?
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.FIELD)
public #interface FieldDefinition {
Class reportedType();
//other fields also
}
Usage:
#FieldDefinition(reportedType=Foo.class)
String bar;

How to decide constraint validator class at runtime?

I have defined an annotation for validation like this:
#Documented
#Constraint(validatedBy = MyValidator.class)
#Target({ElementType.FIELD})
#Retention(RetentionPolicy.RUNTIME)
public #interface MyCustomValid {
//required methods
}
Now, I want to decide the "validatedBy" class at runtime. Like I have a field in my class:
public class MyClass {
#MyCustomValid
MyObject myObject;
}
How do I pass the ConstraintValidator class at runtime. I have different implementations for different cases.
Annotations are compiled into the code at compile time and they can't change, so you need a hack.
Create a validation class which delegates to another validator. The delegate needs to be created at runtime, using whatever algorithm you design. Note that the code might be used concurrently, so you need a thread-safe initialization.

Create custom Annotation as alias for Framework-Annotation?

is it possible to create a custom Alias-Annotation to be used instead of
#SuppressWarnings("unused") // EventBus
public void onEvent(SomeMessage msg) { ... }
like
#EventBusListener
public void onEvent(SomeMessage msg) { ... }
This would be more self-documenting and should include the SuppressWarnings of course...
Sorry if this trivial but my googling failed me so far.
One approach is to write an annotation processor that transforms the AST (the compiler's internal representation of the source code). At each occurrence of #EventBusListener, your annotation processor would insert an occurrence of #SuppressWarnings("unused"). Later phases of the compiler would see the annotation.
Annotation processors do not ordinarily change the source code, so this takes a bit of work. The AST is supplied to the annotation processor as an interface type, so your annotation processor would need to cast this to a concrete class and perform side effects on the concrete class. Project Lombok is an example of annotation processing that modifies the AST during compilation.
You might just want to write the #SuppressWarnings("unused") annotation, though.
You can implement it following way :
#Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.CONSTRUCTOR, ElementType.LOCAL_VARIABLE})
#Retention(RetentionPolicy.SOURCE)
#SuppressWarnings("unused")
public #interface EventBusListener{
#AliasFor(annotation = SuppressWarnings.class, attribute = "value") String[] value() default {"unused"};
}

#Inherited annotation in Java

Herbert Schildt mentions in his book on Java,
#Inherited is a marker annotation that can be used only on another annotation declaration. Furthermore, it affects only annotations that will be used on class declarations. #Inherited causes the annotation for a superclass to be inherited by a subclass.
Therefore, when a request for a specific annotation is made to the subclass, if that annotation is not present in the subclass, then its superclass is checked. If that annotation is present in the superclass, and if it is annotated with #Inherited, then that annotation will be returned.
I know pretty well that annotations are not inherited. Exceptions are annotations, which its declaration is annotated with #Inherited.
I have understood the rest of the annotations which includes java.lang.annotation: #Retention, #Documented, and #Target. and other three—#Override, #Deprecated, and #SuppressWarnings.
I am a bit confused when it comes to the #Inherited annotation. Could someone demonstrate it with a simple foobar example?
Secondly, going through one of the questions regarding this on StackOverflow, I came across this,
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD) #Inherited
public #interface Baz {
String value(); }
public interface Foo{
#Baz("baz") void doStuff();
}
public interface Bar{
#Baz("phleem") void doStuff();
}
public class Flipp{
#Baz("flopp") public void doStuff(){}
}
What use does the #Inherited annotation have when put on the annotation #interface Baz?
Please don't explain me in context with annotations used Spring Framework, I am no in way familiar with it.
First, as the quote you posted states,
it affects only annotations that will be used on class declarations
So your example doesn't apply since you're annotating methods.
Here's one that does.
public class Test {
public static void main(String[] args) throws Exception {
System.out.println(Bar.class.isAnnotationPresent(InheritedAnnotation.class));
}
}
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
//#Inherited
#interface InheritedAnnotation {
}
#InheritedAnnotation
class Foo {
}
class Bar extends Foo {
}
This will print false since the CustomAnnotation is not annotated with #Inherited. If you uncomment the use of #Inherited, it will print true.

If an annotation is associated with a method while declaring it in an interface, can we force the presence of annotation in the implementation class?

This is regarding use of annotations in Java. I associated an annotation with a method while declaring it in the interface. While implementing, how can I ensure that the annotation is carried along with #Override annotation and if not, it should throw a compilation error?
Thanks.
You can't enforce this in the compiler, no. It is the job of the tools which use those annotations to check all superclasses and interfaces when looking for annotations on a given class.
For example, Spring's AnnotationsUtils takes a class to examine for annotations, and crawls all over its inheritence tree looking for them, because the compiler and JVM does not do this for you.
You can't.
You need to write some code to do this (either on your applciation load time, or using apt)
I had the same scenario, and created an annotation of my own:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.ANNOTATION_TYPE)
public #interface DependsOn {
Class<? extends Annotation>[] value();
/**
* Specifies whether all dependencies are required (default),
* or any one of them suffices
*/
boolean all() default true;
}
and applied it to other annotations, like:
#Retention(value = RetentionPolicy.RUNTIME)
#Target(value = ElementType.TYPE)
#DependsOn(value={Override.class})
public #interface CustomAnnotation {
}
Imporant: have in mind that #Override has a compile-time (SOURCE) retention policy, i.e. it isn't available at run-time.

Categories

Resources