Java annotation to get the value of its field - java

Is it possible to pass the value of the parameter to the annotation?
For example:
#MyAnnot
final List<String> list;
I want the content of list to be passed to MyAnnot

What you are asking for is not possible using standard Java.
An annotation is a form of class whose instances may be attached to various elements of a program; e.g. classes, methods, fields, parameters and so on. For annotations with retention policy RUNTIME, an application use reflection to retrieve the annotations associated with a Class, Method, Field and so on.
The problem is that the annotations are associated with (effectively) syntactic elements, rather than instances of those elements. So for example:
public class Thing {
#MyAnnot
final List<String> list;
}
We can use reflection to find the Class object for Thing, and the Field object for list. And from there, we can get the #MyAnnot annotation associated with the Field.
However, the Class, Field and #MyAnnot instance are not associated with any particular instance of your Thing class. If you wanted to get the value of list via your #MyAnnot annotation (somehow) it would need to know (somehow) which instance you were talking about.
The other interpretation of your question is that want (somehow) that each time your application assigns to a Thing object's list variable, that value assigned is also passed to the #MyAnnot annotation. The JVM doesn't do that. It is not standard behavior for annotations. It would be theoretically possible to implement such a feature (with some heroic bytecode rewriting, for example) but I'm not aware of any examples.

Related

Determine Which Parameter in Constructor was used to Set a Specific Field in Class?

I'm working on developing a custom Java object persistence framework as I recently discussed in this question.
One issue I am trying to solve is to force uniform annotation values accross constructor parameter and corresponding field in class.
Is it possible to know which parameter in constructor was used to set a specific field in class via reflection? For example, if constructor contains parameter String textXYZ and class contains field String textABC and in constructor I do: textABC = textXYZ (so field/parameter have different names). Is it possible to know that the field textABC is associated with the constructor parameter textXYZ via reflection?
This would allow me to set annotation just on field and then deduce annotation value of parameter or vice versa..
Thanks
Since Java 7, there's an annotation exactly for that purpose: ConstructorParameters. When placed on a constructor it shows how the parameters of that constructor correspond to the constructed object's getter methods. You can reflectively inspect this annotation and then deduce what fields are related.
Of course, no one is forcing the constructor to be annotated, but that's the only standard way to correlate the fields and the ctor params. Many tool, like Jackson, Jsonb etc have their own annotations for the same purpose.

Is there a way to get all of the non-null members of a class without reflection or getters?

I have a class that that can potentially assign values to 50+ plus variables. I don't want to write getters for all of these fields. I would rather have some way that can report which fields have had a value assigned to them and, what that value is.
I had originally made these private and, I know that reflection basically breaks private. Additionally, Securecoding.org states this about reflection:
In particular, reflection must not be used to provide access to classes, methods, and fields unless these items are already accessible without the use of reflection. For example, the use of reflection to access or modify fields is not allowed unless those fields are already accessible and modifiable by other means, such as through getter and setter methods.
My main concern is mucking up my code by declaring dozens of instance variables(and possibly getters). Later in this project, I will have two more large sets of instance variables that need to be declared as well. I know that I can reduce the use of getters with some clever maps and enums but, that still takes parsing dozens ofnull values. Could anyone suggest another way?
I know only 4 ways to access field of class
directly unless field is private
Using method, e.g. getter.
Using constructor.
Using reflection
The ways 1 and 4 are beyond the discussion.
Constructor usage is not convenient here because huge number of fields.
So, methods the possibility.
It is up to you whether you want to use bean convention or for example builder pattern, but if you need this class for persistency or for serialization into XML or JSON etc you need at least getters.
Now, if you just want to validate the instance after its creation you can declare your interface Validatable that declares method validate() and call it when your object should be ready. You have to however implement and maintain this method for each class.
Alternative way is to use one of available validation frameworks. In this case you validation can be done using annotations. You should remember however that behind the scene such frameworks use reflection.
Here are some links for further reading:
http://commons.apache.org/proper/commons-validator/
http://java-source.net/open-source/validation
http://docs.oracle.com/javaee/6/tutorial/doc/gircz.html

Class design, case for static methods

I had a discussion about usage of static method, briefly the argument is should a class definition have a method as static or instance method in the following scenario. There is a class that defines an entity i.e, what its properties are and what operations are allowed on it.
class dummy{
String name;
String content;
String someRandomOpeation(){
....
}
static String createKey( String inputName, String inputContent ){
return inputName+inputContent;
}
}
The class definition also has a static method that takes in some arguments (say content and date, which defines an instance logically) and use it to construct a key (a string) and return the same. Now if an instance of the message is created it would have the content and date as fields. Is the argument that I can get a key given a name and content and not have to create an instance valid to have the static method. Or does the fact that a pair of name and content logically define an instance say that an instance to be created and get a key from that?
Having a method as static just because you do not wish to instantiate is NOT a valid argument. According to design we use static methods in helper/util classes which may or may not have any properties of its own. These classes basically help in performing some common action which many different classes can use. Also the functions are so modular that they only use the arguments passed to the function to derive the output.
The class mentioned by you will not work because you cannot make a static reference to a non static field constant in JAVA.
Moreover, the disadvantage of using static methods strictly associated with its class fields is that you can not override them.
Is the argument that I can get a key given a name and content and not
have to create an instance valid to have the static method.
No. In this case you almost do not need a class at all. You can always pass data members to class methods, but that does not mean that we do not need classes.
There is an additional argument - encapsulation. It is much clearer and niced to have an instance method getKey() with no arguments and hide the implementation details.
Or does the fact that a pair of name and content logically define an
instance say that an instance to be created and get a key from that?
Also no. The fact itself does not mean that you should create an instance.
The first question here is wether we need a class or not. Do we really have some meaningfull objects, instances of something (dummy)? For example, if I have a library, it obviously make sense to have a class Book, as I have lots of books around. Do you have such a situation? Is this key logically associated with an instance of whatever (dummy here), in a way that Author and ISBN are logically associated with a Book? Does instances of this concept (dummy) has some relationships with some other concepts? Like a Book can be rented.
If most of these answers is yes - than this method should be instance method with no arguments.
Or...
Do you maybe only need kind of a "service" that calculates a key from 2 strings? It this all you need? Are there some other similar "services" that you need, independent on instances. If these answers are mostly "yes", that you do not even need a class. Or you can have a class "Services", with no attributes and with this static method and arguments (and maybe additional methods).
There is also a mixed situation. You still need instances for some other purpose, but you also need a createKey method that is totally independent on any instance, and only provide some global service that is somehow related with the class logic. Then a static method can make sense.
I think your way of thinking is kind of function-oriented instead of object oriented. I think you need a "click" in your mind, which would help you understand the right purpose and the meaning of objects and classes.

Java serialization, UID not changed. Can I add new variables and method to the class?

I have a class that is serialised. Now I need to add a new variable into the class, with setter and getter methods. This class is sent over wire in RMI.
Without changing the UID, can I add new parameters and getter and setter methods for it? I tried to write an example class that is sent over wire, and did not change the UID, and added new parameters and getter and setter methods for it. On the other end, I tested it and I still got the values properly. I had assumed, if I add new parameters, getter and setter methods, I need to change the UID. Am I wrong?
If you hard-code the SerialVersionUID of a class, (to 1L, usually), store some instances, and then re-define the class, you basically get this behavior (which is more or less common sense):
New fields (present in class definition, not present in the serialized instance) are assigned a default value, which is null for objects, or the same value as an uninitialized field for primitives.
Removed fields (not present in class definition but present in the serialized instance) are simply ignored.
So the general rule of thumb is, if you simply add fields and methods, and don't change any of the existing stuff, AND if you're OK with default values for these new fields, you're generally OK.
Wow, a lot of bad information.
Java serialization is +very+ robust. There are a very well defined set of rules governing backwards compatibility of objects with the same uid and different data. the basic idea is that as long as you don't change the the type of an existing member, you can maintain the same uid without data issues.
that said, your code still needs to be smart about handling classes with potentially missing data. the object may deserialize correctly, but there may not be data in certain fields (e.g. if you added a field to the class and are deserializing an old version of the class). if your code can handle this, than you can probably keep the current uid. if not, then you should probably change it.
in addition to the pre-defined rules, there are advanced usage scenarios where you could even change the type of existing fields and still manage to deserialize the data, but that generally only necessary in extreme situations.
java serialization is very well documented online, you should be able to find all this information in the relevant sun/oracle tutorials/docs.
This only matters if you let Java generate a default UID for your class. It uses the actual members and methods of the class to generate it, thus making it invalid once you change the class structure. If you provide an UID for your class then this only matters if you need to deserialize older versions of your class from a file and such.
Want to define few point to highlight the changes which impacts serialization.
Below you will find the link to Oracle Java Docs for more details.
Incompatible Changes
Incompatible changes to classes are those changes for which the guarantee of interoperability cannot be maintained. The incompatible changes that may occur while evolving a class are:
Deleting fields
Moving classes up or down the hierarchy
Changing a nonstatic field to static or a nontransient field to transient
Changing the declared type of a primitive field
Changing the writeObject or readObject method so that it no longer writes or reads the default field data or changing it so that it attempts to write it or read it when the previous version did not.
Changing a class from Serializable to Externalizable or vice versa.
Changing a class from a non-enum type to an enum type or vice versa.
Removing either Serializable or Externalizable.
Adding the writeReplace or readResolve method to a class, if the behavior would produce an object that is incompatible with any older version of the class.
Link from where the above information is taken
http://docs.oracle.com/javase/7/docs/platform/serialization/spec/version.html#6678

Java: What is the fastest way to inject fields using reflection?

Suppose, I have a lot of classes, which are constructed using Java reflection (for some reason). Now I need to post-inject values to fields, which are
annotated with #PostInject.
public class SomeClass {
#PostInject
private final String someString = null;
public void someMethod() {
// here, someString has a value.
}
}
My question is: what is a fast way to set a field using reflection?
Remember, I need to do this very often on a lot of classes, that's
why performance is relevant.
What I would do by intuition is shown by this pseudo-code:
get all fields of the class
clazz.getFields();
check, which are annotated with #PostInject
eachField.getAnnotation(PostInject.class);
make these fields accessible
eachAnnotatedField.setAccessible(true);
set them to a certain value
eachAnnotatedField.set(clazz, someValue);
I'm afraid that getting all fields is the slowest thing to do.
Can I someone get a field, when I know it from the beginning?
NOTE: I can't just let the classes implement some interface, which would
allow to set the fields using a method. I need POJOs.
NOTE2: Why I want post-field injection: From the point of view of an API user, it must be possible to use final fields. Furthermore, when the types and number of fields are not known by the API a priori, it is impossible to achieve field initialization using an interface.
NOTE2b: From the point of view of the user, the final contract is not broken. It stays final. First, a field gets initialized, then it can't be changed. By the way: there are a lot of APIs which use this concept, one of them is JAXB (part of the JDK).
How about doing steps 1 to 3 just after you constructed the object and saving the set of annotated fields that you obtain either in the object itself or by keeping a separate map of class to set-of-annotated-fields?
Then, when you need to update the injected fields in an object, retrieve the set from either the object or the seperate map and perform step 4.
Don't know if it's any good, but this project looks like it would do what you want. Quote:
A set of reflection utilities and
miscellaneous utilities related to
working with classes and their fields
with no dependencies which is
compatible with java 1.5 and generics.
The utilities cache reflection data
for high performance operation but
uses weak/soft caching to avoid
holding open ClassLoaders and causing
the caches to exist in memory
permanently. The ability to override
the caching mechanism with your own is
supported.
Another option, as you say you know the few fields concerned from the beginning, is to ask only for those fields or methods.
Example : see getDeclaredMethod or getDeclaredField in java/lang/Class.html
You can exploit existing frameworks that allow to inject dependencies on object construction. For example Spring allows to do that with aspectj weaving. The general idea is that you define bean dependencies at spring level and just mark target classes in order to advise their object creation. Actual dependency resolution logic is injected directly to the class byte-code (it's possible to use either compile- or load-time weaving).
Fastest way to do anything with reflection is to cache the actual Reflection API classes whenever possible. For example I very recently made a yet-another-dynamic-POJO-manipulator which I believe is one of those things everyone ends up doing at some point which enables me to do this:
Object o = ...
BeanPropertyController c = BeanPropertyController.of(o);
for (String propertyName : c.getPropertyNames()) {
if (c.access(propertyName) == null &&
c.typeOf(propertyName).equals(String.class)) {
c.mutate(propertyName, "");
}
}
The way it works is that it basically has that one controller object which lazyloads all the properties of the bean (note: some magic involved) and then reuses them as long as the actual controller object is alive. All I can say is that by just saving the Method objects themselves I managed to turn that thing into a damn fast thing and I'm quite proud of it and even considering releasing it assuming I can manage to sort out copyrights etc.

Categories

Resources