Can I make a Java Annotation which "extends" #SuppressWarnings? - java

I know that it's not possible to extends Java annotations.
I've created an annotation for a private field which means that the field is likely to appear unused in the class in which it is declared. For this reason, I'm getting a lot of "unused field" warnings on my annotated fields.
Is there any way to give my annotation the behaviour of #SuppressWarnings("unused") so I don't have to doubly-annotate every field which has #MyAnnotation?

The quick answer is "no". Java compiler doesn't know anything about your annotation, so it won't process it the way you want.
But the honest answer is "yes". In this article you can find detailed description of how to write compiler plugin. Chances are you can write plugin, which, in case of finding your annotation, will handle it and won't pass field to unused checker.

Related

#PropertyId annotation "is disallowed for this location"

I got this error and just can't seem to find how to get it working.
My code, simply following some Vaadin10+ exercises:
#PropertyId("string")
final TextField stringField = new TextField("A simple string");
and this won't compile, highlighting the annotation telling the error I put as a title of this question. Compilation error doesn't tell anything more.
Any idea of why it doesn't work? For reference, this is a maven project in eclipse (LTS) and Java 8, and I don't lack any dependency in the pom since I copied the working copy of the pom from the exercise files archive.
Anyway, I'd only need this to do bean validation with javax validators, so I don't need it that hard. I'd just like to understand why it breaks.
The error message you're referring to happens e.g. when an annotation declared to be used on methods is instead used on e.g. a class or an instance field.
#PropertyId in Vaadin is defined with #Target({ ElementType.FIELD }) which means that it should be used for instance fields. Since you are not showing the full context of the code that causes the problem, I can imagine two potential causes:
Your stringField is a local variable inside a method instead of being an instance field in a class.
You're accidentally importing some other #PropertyId annotation instead of the intended one from com.vaadin.flow.data.binder.PropertyId.

Is there a way to annotate the INSTANCE field of kotlin objects?

I have a Kotlin object that has several fields exposed as static #JvmFields. The parser that I use (which I cannot edit or change) looks for public static fields and creates a configuration file based on those. Since the INSTANCE field is public too, the parser generates a new category called instance. Is there a way to add actual annotations to the INSTANCE field? I would want to add the #Ingore annotation to it so the parser does not use the INSTANCE field.
Basically, the answer is no, Kotlin does not allow annotating or altering the INSTANCE fields in any other way. If you believe this could be a useful feature, please file a feature request at kotl.in/issue.
The valid solutions to this problem are:
Make the bytecode analyzing tool Kotlin-aware, i.e. make it behave correctly with Kotlin declarations. Though this requires non-trivial job to be done and does not seem possible in your case, it could be a valuable time investment.
Create another ad-hoc tool that post-processes the classes produced by the Kotlin compiler and adds the annotations you need, then include that tool into your build.

Design a custom annotation to invoke a method in a jar

I'm a bit new to annotations in Java. Is it possible to design a custom annotation which when used in a class automatically invokes a method present inside another Class. TIA.
The answer is "sort of": annotations by themselves do nothing (except "compile time" annotations that affect the compile process).
Meaning: just attaching an annotation to something doesn't magically cause a method to be called at some arbitrary point in time.
This works differently: you have some sort of framework - and at some point you ask the framework to process an object, class, ... And then the framework might check for the presence of certain annotations to "do" something based on that check.
Thus: it is possible to implement custom annotations, and it is also possible to make some "framework" react to the presence of that annotation.
In case you find this answer too generic - well, it can't be more precise/specific than the question ...

How to understand annotation in java And How to implement my annotation in java?

What I have known are:
annotation was added in java 5
annotation can be using in method, class, and property
annotation can work in RUNTIME, CLASS, SOURCE( I don't know how to work with CLASS and SOURCE, and their's features)
annotation with retention which is RUNTIME can be implement when java program is running.
And I want to implement a annotation to have follows features:
ensure class only being allowed to create a instance
ensure methods only being allowed to access method in the class
it is like as friend in c++
it is same as public and private , but more dynamicall, like
#MyAnnotation(allowMethods={xxx.doSomething})
public void getValue(){}
the getValues method only can be accessed in the instance self and xxx.doSomething() method
What should I do and learn in next?
And Where can I learn about these?
I think you might be misunderstanding something there. Annotations are descriptive elements, not parts of your program. You can write as many annotations as you want, and people who use your code will still be able to ignore them.
That said, an annotation that enforces a policy (as yours does) can actually be implemented, either at compile or at runtime, but you need an external mechanism to help you. I can think of 3:
Annotation processing lets you interact with the compiler and process annotations by generating code or by omitting compiler errors. Unfortunately, I don't think it will work for your case, as you want to protect your annotated type from instantiation, and that means the call site doesn't actually have an annotation. Annotation processing only gives you access to the actual code pieces that have annotations, not to those that refer to them.
AspectJ allows you to write policy enforcement aspects and omit compiler errors, based on static pointcuts. The problem here is that static pointcuts have very limited semantics, so while you could forbid the instantiation of your class altogether, or from certain packages, you could not limit the your class instantiations to 1.
The third way, and probably the only sane way is that you use a container like Spring or Guice and configure your class as singleton. As long as you only retrieve your class from the container, it will never create a second instance.
Finally: If you want to limit the number of instantiations of your class, you can always use a classic Singleton pattern approach.

IntelliJ suppress unused warning for API methods

I recently switched to IntelliJ IDEA from Eclipse and I really like the inspectors and find them marking potential errors with warnings for me really useful. I ran into a problem with them that I am unable to solve:
I have some Java projects that are used as APIs in other project, therefore it contains unused methods, which are marked as such:
Unused warning
How can i suppress this for the API methods? Is there an alternative to #SuppressWarnings("unused"), since this also suppresses warnings about unused warnings inside the method and doesn't make it clear to the reader that this method is designed for API use instead of just not being used in the current project?
#Sebastian's suggestion to have your class implement an interface is probably the best way to solve this issue from a good design standpoint. But when that is impractical, there is an alternative...
The "Unused declaration" inspection allows you to configure "entry points" (i.e. a public external API) to ignore. As part of that you can configure "annotations". Anything annotated with the configured annotation is seen as an entry point.
Just configure the inspection to use an annotation that you annotate your public API methods with, either one from a library -- such as #API Guardian (used by some open source projects such as JUnit 5) -- or one you create. Using a library will of course make things easier and consistent across projects. In the below example I used a #PublicApi annotation I created. Notice the method is not highlighted as unused. But the foo String still is highlighted as unused, which is what you want:
As an alternative to opening the Settings dialog, and to limit the impact on your programming flow, you can also use a Quick Fix Intention to add the desired annotation to the "Unused Declaration" settings. After annotating with the desired annotation, place your cursor on the highlighted unused method (or class) name, and invoke the "intention actions and quick-fixes" popup via Alt+Enter or ⌘↩ (or by clicking on the light bulb icon ) and select "Suppress for methods annotated by '{annotation}':
Write an interface for your class. Methods that implement an interface method are not marked as unused. instead the unused methods from the interface are marked as unused but here you can safely use #SuppressWarnings("unused") because you do not have a method body. You could even write #SuppressWarnings("unused") above the whole interface.
In short, no and this isn't really anything to do with IntelliJ, Javac the Java compiler will produce these if you ask it to.
If your method needs this annotation, then that will be for the entire method. However if you just wish a field to be annotated, then that is possible:
#SuppressWarnings("unused")
int iii = 0;
In summary, the method annotation will cover the whole method, placing it per field or instruction will cover that single line.
intellij can do this for you.Just hit Alt+Enter on the occurance that gives you the warning. Some suggestions will pop-up one of them being remove field. there will be an arrow field at the end of the suggestion. Using your arrow keys navigate to the option and use the right arrow to bring up another menu. One of the options will be suppress this for method and suppress this for statement etc.
Suppress for statement will cause this :
//noinspection unused
int iii = 0;
However I have to urge you to heed to the warnings being provided by Intellij and not blindly suppress them.

Categories

Resources