I want some of my methods to run before and after the Lombok #Setter.
For example:
#Setter(after="save")
private String name;
This should run method called "save" after the original setter has assigned a value to the field.
So after compilation it should look like this:
public void setName(String name){
this.name = name;
this.save();
}
Maybe there is something I could do with "onMethod" parameter? Sorry, I'm not professional in annotations.
There is currently indeed no way to do this; onMethod isn't going to help either (SOURCE/DISCLAIMER: I'm a core lombok dev).
We do have some plans to add such a thing, but before you go ahead and write a PullRequest to add such a feature, discuss it first. There are various ways to go here. The primary issue is syntax.
You can't put java code in an annotation (you can put it in a string but we veto such a move; your IDE is not going to help you, it's got the wrong syntax highlighting, and so on). You can't, unfortunately, put a method reference in an annotation either. You could put a string in there that mentions a method but we don't like that either (again, wrong colouring, no IDE autocomplete support).
That leaves magic naming (you make a method called afterName), but at that point lombok saves you nearly nothing, so why not just write the setter. A second option is to have a single 'validate' method that is called after any setter and is e.g. marked by an annotation. That's more the direction we're leaning into.
There's more to consider: Sometimes you'd want to mutate the incoming value before assigning it, and the same mutation should be done in case you have a builder, or have a constructor that accepts this param, as well. Thus, we have:
Post-set actions after any setter and construction, such as save().
Pre-"setting", validate and/or mutate, after any setter and construction. For example, let's say you have a setAge() method and you want to throw an exception if someone attempts to pass a negative value. The set shouldn't even happen, so a post-set handler can't do the job (it'd be too late, the object is already in an invalid state and you'd want to avoid this). Complication: Given that we want to do this pre-setting the field, how does this method get the values, then?
Hopefully that illustrates why this feature isn't (yet) in lombok and why it's a matter of a simple PR to add it.
Related
For instance in main method I havesetFirstName() and call the Contact class to do this.
In the contact class I know I should use:public String getName()
and then public void setFirstName(String name)
I know this is the right way to do that.
But instead, I find that if i do:
public String setFirstName(String name)
{
return this.name=name;
}
this will also work and I don't need to use getName()method.
Can anyone please help me out why is that? Is my accessor/mutator method correct?
It is the very idea of an accessor that it only reads but does not modify. That is a useful convention, because if done consistently it makes reasoning about some code you don't know a lot easier. Normally, you shouldn't have to expect weird side effects from something named getX(). It may be ok to do some lazy initialization, but it is clearer if such "lazy getters" are named getOrCreateX() or similar to give the user a hint that the first use might take a bit longer/involve some expensive operation.
A mutator that returns something may be useful, but it will help users of your class if you name it in a way that gives a hint about what it returns. Is it an error code or the previous value? People don't expect return values from something named setX(), so they will be surprised to see such a signature and have to look at the documentation of your class to see what it does.
Summary: Always code as if someone else will have to take over your code any moment - don't do things that would be surprising. Even if you never hand your code to anyone else, your future self will thank you for picking names that explain what the method does.
Note: Your implementation of the setter is not very useful, as it always returns the new value you just passed in.
Getters and setters are just a convention. The compiler doesn't recognize them specially, or anything like that.
A getter, for example public String getFirstName() {return this.name;}, is just a method that returns the value of a field.
A setter, e.g. public void setFirstName(String name) {this.name=name;}, is just a method that sets the value of a field to its argument.
There is nothing forcing you to create getters and setters, and nothing bad happens if you don't, or if you decide to implement them differently. The reason they're normally written that particular way is that it works well most of the time. But you don't have to.
You have created a method that:
Sets the value of the name field to its argument.
Returns the value of the name field.
Nothing wrong with that, it's a perfectly valid method.
Is it useful as a setter? Sure, it sets the value.
Is it useful as a getter? Nope - tell me, how would you use it to get the person's first name?
But it's a perfectly valid method, and it's not "right" or "wrong", it's just not particularly useful.
The setters and getters must be properly implemented because some frameworks depends on them for proper functioning.
Mocking frameworks such as Mockito ,DI frameworks and some xml serialization techniques depend on set and get methods.
I was never really strong in reflection and I seem to have stumped on a problem that seems trivial but doesn't turn out that way. At least for me. I have a bean with a few getters , then in a service I use Reflextion to loop over said methods and at a certain point I end up with the get method I want. I invoke the method to get the value, and now I like to know the name of the field I just asked the value from. There is it where I get stuck.
get method
public String getTest(){ return test }
invoking method by reflection
Object value = method.invoke(jsonObject, new Object[]{});
Now I like to do something like this
String fieldName = method.findTheNameOfTheField();
I find lots of examples to call the getter from the fieldname but nothing on how to do the reverse. Is this even possible without parsing the name of the method and just cutting is and get from the method ?
I invoke the method to get the value, and now I like to know the name of the field I just asked the value from.
No, you can't do this - at least not without analyzing the bytecode itself. Don't forget that the getter can contain any code. Maybe it doesn't use a field. Maybe it uses more than one field. Maybe all the properties use a map. Maybe it uses a field, but then changes the result (e.g. copies a list).
You should consider whether a change in your design would remove the need for this in the first place - I can't think of many cases where it would be a good idea.
For working with JavaBeans, the Bean Introspector makes life easier.
Tutorial
http://v1.dione.zcu.cz/java/docs/tutorial/javabeans/introspection/index.html
Examples
http://www.java2s.com/Code/Java/Development-Class/IntrospectingaBean.htm
http://www.znetdevelopment.com/blogs/2012/04/11/java-bean-introspector-and-covariantgeneric-returns/
http://www.javablogging.com/inspecting-your-java-beans/
http://softwaresalariman.blogspot.co.uk/2011/11/minimal-javabean-introspection-example.html
This uses reflection but hides much of the details like; Do I want getValue or isFlag for a getter.
The only thing you can do here is to rely on the JavaBean convention, i.e. that the method getFoo() returns the value of the field foo.
A getter may not necesarily return a field; here's a really trivial example
public getAge() {
return currentdate - birthdate;
}
The whole point of getters is that they may return a field, but they may also return something else, abstracting internal logic from those who call the method.
Is there an existing library that allows me to annotate a Java method as #Const, so that the compiler (using apt I presume) will flag an error if it updates a field, or invokes a non-#Const method on a field; and annotate a parameter as #Const, so that the accepting method cannot invoke any of its non-#Const methods, or update any of its fields?
(Basically, trying to add const-correctness to Java using annotations; there are some obvious details not covered in the question above, such as assigning to/from a #Const-typed parameter, etc.)
I've found this: http://confluence.atlassian.com/pages/viewpage.action?pageId=182158080 but it seems like it's only available as part of IDEA.
Following a request for clarification below, here's sample code to show what I mean:
class Person {
private String name;
private String address;
#Const public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
... etc. for address
}
Now, if I define a method such as:
void processPerson(#Const Person p)
a line such as: p.getName() would be OK in processPerson, since getName was marked as a #Const method. But calling p.setName() from within processPerson would be flagged as an error.
Note that this is very different from final: if the parameter was defined as final Person p, any assignment to p would have been illegal, but it's still perfectly valid to modify what p refers to (either using p.setName(...) or even more directly, with p.name = ....
JSR-305 supposedly does just about what you're looking for
Personally, I'd see if I can use Hibernate Validator - Bean Validation (JSR-303) for that. It's a wonderful little lib (doesn't depend on hibernate, it's small) and it does wonders to keeping your data clean. See the documentation.
A google guy also started Contracts for Java recently, but it might not be production quality yet.
Take a look at the Checker Framework, which basically has checkers that try to detect software defects [JSR-305] via an extensible type annotation system [JSR-308].
It has an immutability checker (2 actually) which allows you to annotate code with immutability annotations like #Mutable, #Immutable, and #Readonly. This tool differentiates between an immutable instance and a read-only reference.
I love this framework and mainly use it for null checking, but I am trying to start using the immutability checker and interning checker more.
annotate a parameter as #Const, so that the accepting method cannot invoke any of its non-#Const methods, or update any of its fields?
Would look like:
void addFriend(#ReadOnly Friend friend) { this.friends.add(friend); }
allows me to annotate a Java method as #Const, so that the compiler (using apt I presume) will flag an error if it updates a field, or invokes a non-#Const method on a field; and
It would look like this for the example in the question:
public String getName(#ReadOnly Person this) {
return name;
}
The #ReadOnly here indicates the receiver (the this instance whose method is being called) should NOT be modified. Despite the apparent extra parameter, the method is still called as usual:
#ReadOnly Person person = new Person();
person.getName();
I am seconding #AlexR comment, this can be done using AspectJ, something along these lines:
public aspect ConstAspect{
declare warning : withincode(* *(..,#Const (*),.. ) ) : "Calling Const Method..";
}
This is not correct for your requirements, but I basically want to show an approach, In the above case any method which has a #Const on a parameter is tagged with a warning. With a better joinpoint, all the points of concern can be tagged with an error.
const was in C++. Java apparently ditched it on purpose. And now people growing up without really experienced const think it's a good idea.
Once you marked one method as const, it'll spread like cancer, pretty soon you'll find yourself const almost everything. It would have been better to have a not-const.
Utterly it's useless. It's only appealing academically, doesn't help anybody in real programmnig.
Looking at some code cleanup and I was wondering the best way to deal with this:
Have a class with some private variables like:
myBool1, myBool2, myBool3
myInt1, myInt2, myInt3
myString1, myString2, myString3
What's the best way to do a getter function that is generic to the return value? So if I do a call to the getter with something like:
myNewBool=<blah>.get("myBool1")
myNewString=<blah>.get("myString2")
myNewInt=<blah>.get("myInt3")
Anyone have any suggestions?
You can't really have a generic getter if you don't know what you want to get, for example :
boolean myNewBool= get("myString1");
If get returns something, but you don't really know if this something is compatible with a boolean, and terrible things could happen.
You could try this:
public <T> get(String element){
return (T) elementToGet;
}
But you would have to specify the return type when you call the get method.
String element = myObject.<String>get("element");
Here are the bad sides :
You can't work directly with primitives
You can have a lot of ClassCastException
If you misspell an attribute name you won't see it until you run it
You don't expose a nice public API, people would have to know evert possible attribute to use it, and as said above, a misspelled attribute (or an inexistant one) wouldn't be seen until runtime.
You have to know the return time and type it each time you use your method
You would have to type a really long (and smelly) code in your get method either to use each possible attribute (if you still want have some private and not accessible) or worse, use reflection to find the right attribute.
So definitively not a good idea.
What you can do instead is using the good old getters//setters and if there is a lot of them, generate them with your IDE.
Another way would be to use the project lombok.
Resources :
Project Lombok
On the same topic :
Create automatically only getters in Eclipse
Eclipse Generate All getters setters in package
Java Getters and Setters
First you should ask what would be the pros and cons of such a solution.
Pros:
One method instead of many
Cons:
Non-intuitive to the users of your class (classical getters are more common)
You cannot have an overload that only differs by a return type, therefore you will have to have methods like getBool, getInt etc.
It's slower - you have to pass the string, check for validity, do a lookup in a map...
The only advantage of your proposed solution would be not repeating the get()/set() code. However, as these methods are usually generated by your IDE and contain only a single-line command, I wouldn't see that as a big problem.
To answer your actual question - you can create a HashMap with name-attribute mapping. Alternatively, you may use Java reflection to access the attributes. The second solution is more general but also harder to write.
This is really a terrible idea. I'm not sure why creating a getter/setter for each private variable is a problem, but passing around strings that map to a variable's symbolic name would be hard to maintain and confusing. You don't need this to be generic; each variable represents a different quantity and they should be accessed as such.
It wouldn't be clean up but mess up. I'd either created 3 getter methods for the fields or redesign it completely. But calling a function, with a name of a field to return, as an argument can bring nothing good.
When you code, you must be refactoring your code for all the time you are coding. But not like this. Solution is delegating logic to another class, wrapping code into more utilizable methods or changing and simplifying domain objects...
I'm now working with code that looks like this
public String getName(User user) {
user.setSth(...);
return user.getName();
}
I think it's bad practice to change objects passed as parameters. Is there a tool that detects that kind of code? I looked at findbugs, pmd and checkstyle, but could not find any check for this.
P.S. sorry for bad example.
I think you are already on the right track: your best tool to detect this sort of code is almost certainly Findbugs. However, you will probably need to write your own detector for this pattern. Here is an example of how you would write a detector, though it isn't exactly the detector that you're looking for.
Caveat: I don't really agree that a side-effecting getter is always bad style. However, if you really want to find that sort of thing, I would recommend Findbugs.
You won't find anything because, from a tool's point of view, "getName" and "setSth" are just method calls. Humans say "this is a getter" and "this is a setter" but tools don't. In fact, getName() is not a getter because getters don't accept arguments.
So the tool can't see anything unusual because methods change objects all the time.
If you want to enforce this rule, have a look at extending findbugs and PMD. Both allow you to define additional constraints. What you're looking for is probably:
If method name starts with "get"
AND method body calls method of any object passes as parameter
then print a warning. That shouldn't take too long. Run this and you will see how many "false positives" you get (warnings about methods which are actually OK). This will help you determine whether it's worth to pursue this further. Plus you'll have a new item to add to your CV :)
You could make User immutable (declare it final, declare all properties final and remote the setters. I know that isn't practible everywhere but in many places that is good and you will have no problems in passing that to other functions).
If you have to "change" something, you can implement functions like newId in that sample:
public final class User {
private final String name;
private final int id;
User(String name, int id) {
this.name = name;
this.id = id;
}
public User newId(int newId) {
return new User(this.name, newId);
}
//getters here;
}
The built in String, Integer, ... classes do that, too.
You can create an interface called UserView containing only "getters", make User implement it and use the new UserView interface as the type of parameter.
interface UserView{
public String getName();
...
class User implements UserView...
public String getName(UserView user) {
user.setSth(...); // Will not compile
return user.getName();
}
Actually this is something that in C++ was very easy to do via the const qualifier. You would define a parameter as const and for that parameter you could only call methods defined as const - usually, getters.
In Java this is absent and frankly, I don't really mind. As mentioned there are source code analyzers which can check this behavior, as well as meta-programming methods to do this as well.
Personally, I believe that if the method is named properly, there is no problem of passing an object to it so that is it modified.
There are tools that can "reason" about code on a higher level than compilers typically do. Declarative Metaprogramming for example is a discipline that allows writing programs to check if another program conforms to a certain design, or, conversely, to mine for code smells and anti-patterns.
Some links:
http://prog.vub.ac.be/DMP/
http://www.cs.bris.ac.uk/Publications/pub_master.jsp?id=1000273
and for the rest
http://www.google.com/search?num=100&hl=en&q=Declarative+Metaprogramming
You're looking for something like "const" in C++ that will enforce making the parameter value as immutable as the reference that's passed in. Immutable objects guarantee that, if you can live with them.
You're arguing that this is "bad" because side effects like this can surprise a user. That's valid, but it's only harmful if it's an unwanted surprise.