Simulate `property` in Java: how to use public field as property? - java

In playframework, it uses javassist library to let the public fields of a class can be used as property.
See the example:
public class User {
public String name;
}
User user = new User();
user.name = "Freewind"
System.out.println(user.name);
In compilation time, play enhanced the bytecode with javassist, the final code is similar to:
public class User {
private String name;
public String getName() { return this.name; };
public void setName() { this.name = name; };
}
User user = new User();
user.setName("Freewind");
System.out.println(user.getName());
You can see not only the field name has getter and setter, but also the invocations of it changed to getters and setters.
I wonder if there is any other way to do the same (use other things than javassist)?
I found Annotation Processing Tool, but I'm not sure it can do it.
Or aspectj? Or something else?

You can look at Project Lombok, which does something similar, but with annotations. With project lombok you do need to use the getters and setters in your own code.

Not without other tools.
Unlike C#, Java does not support properties.

Related

Using Java annotation to generate serialization code?

Serialization is a lot of boilerplate. I was wondering if I could use annotations to write that for me, thus allowing the structure of the object to double as its on-disk format.
I know Jackson exists but ObjectMapper feels too magical and I'd like to just have something like this:
#SynthSerializer
public class Foo {
public final String name;
public final String description;
public Foo(String name, String description) {
this.name = name;
this.description = description;
}
}
//Following code generated at compile time by #SynthSerializer:
public class FooSerializer: implements Serializable {
//Boilerplate, you know the drill
}
Incidentally, from what I understand modifying source code using annotations is a hack, but creating altogether new classes (like in my example) is an intended use case for annotations. That's true, yes?
Anyway, is this kind of generation possible with annotations? Is this a sane way to do something like this? And do annotation processors that already do something like this exist?

Export specific fields on XML extraction in Java

I am using #XmlRootElement annotation to get XML data from the database.
Right now, if I put #XmlTransient to getters, the fields are ignored.
For example:
public class Student {
private Integer studentId;
private String studentName;
#XmlTransient // Do not get student id
public Integer getStudentId() {
return this.studentId;
}
public String getStudentName() {
return this.studentName;
}
...// Setter goes here
Then, student ids are not appear in the XML file.
However, can I do this in the opposite way? I want to specify fields that I want to have in the XML file - there are too many fields in the Student class.
My server(Spring Framework 3.2.3) also uses the Jackson library, so I wonder I could use it if that is possible.
You could annotate your class with:
#XmlAccessorType(XmlAccessType.NONE)
Now you have to explicitly map properties in order to be serialized. See the Javadoc: http://docs.oracle.com/javaee/7/api/javax/xml/bind/annotation/XmlAccessType.html

Eclipse plugin for Fluent API methods

I'm looking for an eclipse plugin that can generate fluent API methods in my beans.
For instance, given this bean:
public class MyBean {
private String name;
private int age;
//Setters and getters
}
Is there any eclipse plugin that generates these methods for me?
public class MyBean {
private String name;
private int age;
public MyBean withName(String name) {
setName(name);
return this;
}
public MyBean withAge(int age) {
setAge(age);
return this;
}
//Setters and getters
}
I've found a google plugin that generates Builder objects, but I prefer fluent API inside each Bean class.
While can't find anything, you can do like me.
Generate the setters, then "Find" (checking "regular expressions") for:
\tpublic void set(.+)\((.+)\) \{\R\t\tthis\.(.+) = (.+);\R\t\}
 and replace with:
\tpublic [PUT_TYPE_HERE] with$1\($2\) \{\R\t\tthis\.$3 = $4;\R\t\treturn this;\R\t\}
Probably there's a simpler expression, but this works ;)
[UPDATE] # 07-MAR-2018
I'm now using lombok which generates getters, setters and builders throught simple annotations. (#Getter, #Setter and #Builder respectively)
It can generate with methods using the #Wither annotation too, but unfortunately its an experimental feature so it should be avoided.

Extract annotation parameters from a bean/class

I am using the #JsonProperty(name = "property_name") (Jackson) annotation wherever the property name in the json is different from the property name in my object. Is there a way I can programmatically access this information somewhere else in code?
Example:
public class Entity {
protected long entityName;
#JsonProperty("entity_name")
public long getEntityName() {
return entityName;
}
public void setEntityName(String entityName) {
this.entityName = entityName;
}
}
What I need is a method to map entity_name to entityName. e.g, getActualFieldName("entity_name") should return "entityName". I can keep a separate file with all these mappings, but I don't want to do that because this information is already present in the form of #JsonProperty annotations. If I can extract it from there somehow, it would simplify things a bit.
Check this Helper utility. getAnnotationParameter

Annotate Methods to choose them later

Is it somehow possible to annotate a Java Method in that way that i later can give another Method a Field Identifier or something like that, so that this Method can call the right one?
I know that normally you would do this with interfaces, but in my case this would be a immense count of interfaces... I need to use this in Entity Classes for my Database (and i'm not allowed to use a ORM Mapper)
For example: I have the Entity
public class Account{
private String username;
private String password;
private String name;
private String mail;
public void setUserName(String username){
this.username = username;
}
public String getUserName(){
return username;
}
[all other getter/Setter...]
}
Now i want to tell a Method that it need to validate a Field, for example the username field.
The Method that does should look like this:
public void validateField(XXX Field, Entity entity) throws ValidationFailedException, EmptyFieldException;
where XXX is somehow the FieldIdentifier.
Is that in any way possible in Java?
My only guess it that i Use public static final ìnt stuff in there to give every field a Method or so...
What do you use? I don't see any annotations from which I can guess your framework. If you use Hibernate, you can use something like #NotNull or something else, or even do your custom validation:
This is how you would go with your example:
public class Account{
#NotNull(message="This field should not be null")
private String username;
#NotBlank(message="This string should not be empty or null")
private String password;
private String name;
private String mail;
public void setUserName(String username){
this.username = username;
}
public String getUserName(){
return username;
}
[all other getter/Setter...]
}
http://silentwalker.wordpress.com/2009/04/07/custom-validation-in-hibernate/
You can also create your own annotations without using any framework and use them #prepersist or whatever. Basically the sky is the limit.
P.S Since you don't want to use any non internal code, here is how you can approach:
First, you can define an annotation
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.FIELD)
public #interface NotNull{
public String message() default "";
}
Then, before persisting the class, you would inspect its fields:
So, you have something like this:
Field[] classFields = yourObjectPrePersist.getClass().getDeclaredFields();
for (int i = 0; i < classFields.length; i++) {
classFields[i].setAccessible(true);//take notice that if you use a SecurityManager, you should work around it
if (classFields[i].getAnnotation(NotNull.class) != null) {
Object value = classFields[i].get(yourObjectPrePersist);
//here check if value is null or not and then return the message
if (value == null) {
throw new SomeException(((NotNull) classFields[i].getAnnotation(NotNull.class)).message());
}
}
}
Annotations don't seem like the right solution to the problem you describe.
One possibility would be to pass in the name of the field that needs to be validated, then used the java.beans.BeanInfo class to access the field values of the Entity. This will allow you to access arbitrary attributes of an object without having to deal with all of the complexity of reflection.
You can use reflection for this; see the documentation for java.lang.reflect.Field. The caller can pass in the field-name as a string, and validateField can use something like Field f = entity.getClass().getField(fieldName).
But this is not usually a great idea . . . reflection is awesome, but it requires a lot of boilerplate code, and you pay a high price in maintainability. (You also pay a performance penalty, though in my experience the maintainability penalty is much worse than the performance penalty.) Personally I use reflection a lot in test code (it can help in writing extremely comprehensive tests), and I make use of frameworks like Spring and Hibernate that depend on reflection, but I avoid it in my own production code.
You could use a generic interface
public interface Field {
public String getValue();
}
and call your validate method with anonymouse classes
validator.validate(new Field() {
return account.getUsername()
});
(or with old java)
validator.validate(new Field() {
public String getValue() {
return account.getUsername();
}
});
Otherwise what about using java.lang.Methode directly?
P.S.: Sorry for the quote, stackoverflow did not let me post my text directly, said it was not formatted correctly :-/

Categories

Resources