If we have an annotation that is used to set certain Class-specific Constants, declared this way:
#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
public #interface Tooltip {
String value();
}
Used like so:
package applicationroot
#Tooltip("createCubeTool.tipText")
public class CreateCubeTool extends EditingTool
{
}
with this in the supertype:
public abstract class EditingTool
{
public String getToolTipText()
{
//Don't worry about this, other than that it requires a custom value Per Concrete class.
return null == tooltip ? null : Translate.text(tooltip.value());
}
}
Where should the annotation be declared?
Leaving aside questions regarding the overall structure of the project, it occurred to me that this particular annotation is only useful in subclasses of the scope of the ModelingTool type. Does it make sense to declare it in an entirely separate package, package applicationroot.tool.annotations; as one contributor suggested, or would it be better declared as a member of the ModelingTool type that uses it?
All references that I have found so far talk about how to declare a custom annotation, but not where they fit into a project's overall structure.
In general, if the text is variable for some reasons, for example it needs to be formatted or transformed before output, declaring it as an instance member maybe the better idea.
On the contrary, a decided CONSTANT can be defined in the meta info of an annotation. Remarkably, you have to use reflection to get the meta info which may degrade performance. The reflection brings a deep call stack.
In this case, I don't think it's worth using annotation. You have little expected benefit from the refactor, except an ostensibly elegant code.
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.
A tonne of code at my company uses the javax.inject.Named annotation with the default value, which the Javadoc indicates is the empty string "".
For example:
#Named
public class Foo {
...
}
This does not appear to add any value, since the empty string doesn't have any semantic meaning. If I remove the #Named annotations will there be any harmful effects?
The question What is javax.inject.Named annotation supposed to be used for? describes how #Named functions, but doesn't explain any special significance of the empty string, or why it would be necessary or beneficial to omit the actual name.
The question When should you explicitly name a Managed Bean? likewise talks about when you would want to use names to differentiate injectable beans, but doesn't provide any rationale for the use of the empty string as a name.
Can I delete these un-named #Named annotations without breaking anything?
#Named (javax.inject.Named) is equivalent of #Component (org.springframework.stereotype.Component).
When used to annotated a class, it indicates that the class will be scanned and registered. If name is not given, DI framework will use the class type when injecting dependencies.
In short, you can't remove those #Named annotation. If you do, everything will be compiled as normal. However, at runtime, you'll get runtime error something like cannot find bean xyz.
It's impossible to know if you will break anything without analyzing all the code that constructs injection keys and all the code that injects any of these bindings.
In some JSR-330 implementations (e.g. Dagger) it's not possible to use a #Named annotation with a value constructed at runtime, but in other implementations (e.g. Guice) it is possible and in fact commonly done.
For example, I could imagine a Guice module like:
public final class DynamicFooModule extends AbstractModule {
private final String whichFoo;
public DynamicFooModule(String whichFoo) {
this.whichFoo = whichFoo;
}
#Override
protected void configure() {
Key<Foo> fooKey = Key.get(Foo.class, Names.named(whichFoo));
Provider<Foo> fooProvider = getProvider(fooKey);
bind(Foo.class).toProvider(fooProvider);
}
}
This provides a binding for an unannotated Foo which delegates to a #Named(x) Foo, where x is determined by a constructor argument to the module -- which could be constructed at runtime, or derived from some default somewhere, etc.
You could imagine code building an injector like:
Injector injector = Guice.createInjector(
...,
new DynamicFooModule(getSelectedFooConfig()),
...);
Where getSelectedFooConfig() might return "" as a default or fallback.
In a situation like that, #Named without any name could be a reasonable fallback value to use. If your application is doing anything like that, then it is not safe to remove the #Named bindings, because an un-annotated binding is not equivalent to a binding with an empty string.
I still would argue that this is not a good design: it would be better to use a dedicated qualifier annotation for this purpose (e.g. #ConfigBased("foo-config")) rather than just using #Named. If you were doing that then you could at least identify which strings were being used (or, better yet, eschew strings and use an enum instead).
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.
After spending quite sometime searching through scala documentations I have not found this particular bit of information. Or at least not phrased in a way I could easily understand or get any certainty out of.
I have this annotation:
class MyAnnotation extends StaticAnnotation {
def macroTransform(annotees: Any*) = macro myImpl
}
And I have used it on two or more classes like this:
#MyAnnotation
class One {}
#MyAnnotation
class Two {}
I would like to know if the annotees will contain both the classes or if the macro will be executed twice (one for each instance of the annotation). Will I have?
annotess.map(_tree).toList == List(oneClassDef /*classdef of One*/, twoClassDef /*classdef of Two*/)
> true
Is it possible to make it so that the annotation trigger only one application of the macro with all the annotated classes in the annotees at once?
Annottees only include the directly annotated member + an enclosing definition (class/trait) for a value/type parameter + a companion for the annotated member (or for the enclosing definition for a value/type parameter).
Unfortunately, it's virtually impossible to implement your request in the current namer/typer architecture of scalac (and, to the best of knowledge, in dotc as well), so I'd suggest a workaround - annotating a definition that encloses all the classes that you want to process.
I have a class that is annotated as the #XmlRootElement with #XmlAccessorType(XmlAccessType.NONE). The problem that I am having is that the superclass's methods are being bound, when I do not want them to be bound, and cannot update the class. I am hoping there is an annotation that I can put on the root element class to prevent this from happening.
Example:
#XmlRootElement
#XmlAccessorType(XmlAccessType.NONE)
public class Person extends NamedObject {
#XmlElement
public String getId() { ... }
}
I would expect that only the methods annotated #XmlElement on Person would be bound and marshalled, but the superclass's methods are all being bound, as well. The resulting XML then has too much information.
How do I prevent the superclass's methods from being bound without having to annotate the superclass, itself?
According to this StackOverflow post:
How can I ignore a superclass?
It is not possible with JAX-B to ignore the superclass without modifying the superclass.
Quoting the relevant portion of that post:
Update2: I found a thread on java.net
for a similar problem. That thread
resulted in an enhancement request,
which was marked as a duplicate of
another issue, which resulted in the
#XmlTransient annotation. The comments
on these bug reports lead me to
believe this is impossible in the
current spec.
Just add
#XmlAccessorType(XmlAccessType.NONE)
in front of EACH superclass declaration (and the class itself).
In your case:
#XmlAccessorType(XmlAccessType.NONE)
class NamedObject{
[ ... ]
}
Remember that this has to be done really for each superclass, it is often
forgotten when dealing with huge class dependency trees.
Interfaces, of course, don't need any JAXB annotations.
I know this question is quite old, but there is a kind of solution which works if your superclass is in the same package as its child.
Create a package-info.java in your package and insert
#XmlAccessorType(XmlAccessType.NONE)
package my.package.with.classes;
Obviously, it sets XmlAccessType.NONE upon all classes in the package. Myself, I use it in every package in our domain model. Therefore, I'm pretty safe. However, if your class is 'out of reach', f.e. it's in the JDK, use the solution from the accepted answer in [JAX-B] How can I ignore a superclass?.
I hope it's helpful for anynone who stumbles upon this question as I did.
I'm facing the exact same problem.
My superclass does not handle any JAXB annotations (it doesn't have to) and I would like my subclass not to include superclass properties while marshalling.
Adding the XmlAccesorType on superclass cannot be the solution as I have no way to modify the superclass.
Is there any other solution?
Replace your JAX-B implementation with MOXy and you can do anything you want. It has a ton of extensions that go above and beyond normal JAX-B, one of which will allow you to ignore inherited properties, etc. It also supports moving JAX-B annotations to an XML mapping file so you can keep multiple sets of mappings.
A solution I have found, but which might not work for you depending on what you want to do, is to override the getters you want to ignore and let them return null. The JAXB specs, and by extension the implementations, ignore fields that contain a null value. Note that if you still need to be able to access the superclass value itself using the subclass, you may need to add a secondary accessor method that is not a getter and adjust your code accordingly.