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.
Related
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.
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Are Getters and Setters evil?
I can't find a logical reason behind having a private variable with a getter and a setter that does nothing but directly handling the value being preferable to having a public variable.
Am I missing something?
Because,
Validation is one reason. Keeping the field name out of the public API also allows you to change it later without breaking the API. And it allows you to change the class later in other ways as well, e.g. moving the field to some other class (so that the public setter would call a setter in a different class). Having the setter called also allows you to do other things, e.g. notify interested other components of the change of value. None of this would be possible if the field was accessed directly.
They are preferred to future proof the code. In the future if you want to eliminate the variable or use another variable to derive this variables value - the change is simpler. You just need to change the getter/setter, the rest of the code remains unaffected. This is not the case with direct access to the variable.
As #user370305 already mentioned one reason is validation.
Other reason is types conversion. Setter may accept string and parse it to integer.
Yet another reason is data encapsulation. It is not necessarily to have a simple filed stored in the same class. Method setName(String) of class Person may store the name in more complicated data structure. Using simple field does not allow you to change the internal implementation of class Person without affecting code that uses it.
EDIT:
yet another technical reason.
It is much easier to discover and debug code with getters and setters. If some field is changed unexpectedly you can just toggle break point into appropriate setter and find the problem very quickly. If this field is public and you have 1000 references to this field you theoretically have to put 1000 breakpoints in all these places.
1. Encapsulation has different use in different context, In design patterns its like behaviors that keeps changing needs to be encapsulated in abstract class, or interface.
2. Having private instance variable and public getter setter is b
3. Its mainly done to Validate the input from the user... Setting the value to an instance variable directly is dangerous.
Eg:
int dogAge;
System.out.println("My dogs age is :"+dogAge);
Now what if someone gives a negative age... then.......???
So we must do it this way...
int dogAge;
public void setAge(int age){
if (age>0){
dogAge = age;
}
else{
System.out.println("Not a valid age");
}
}
public int getAge(){
return dogAge;
}
System.out.println("My dog age is :"+ getAge());
Its simple .. if you make those variable public then you give rights for ading any values to them .
But if you do that via getter or setter ... you can put checks over it and control the input or conversion without letting the end user know that
eg :
getName(){
return firstName+lastName;
}
or
getData(){
// code to convert byte to Mb or whatever you like to represent
}
Use of accessors to restrict direct access to field variable is preferred over the use of public fields, however, making getters and setter for each and every field is overkill and considerd as not a good practice. It also depends on the situation though, sometimes you just want a dumb data object. Accessors should be added for field where they're really required. See this link to know more about it Getter Setter: To Use or Not to Use.
I can't find a logical reason behind having a private variable with a getter and a setter that does nothing but directly handling the value being preferable to having a public variable.
Consider that any additional code that you put into getters and setters adds to complexity and also needs to be tested. For a small system which is fully controlled by you, there may be little benefit in using getters and setters. Use your professional judgement. You may not need the future proofing and added complexity. Or it may be more important to you to have the efficiency and simplicity of direct access.
Personally, I think that getters and setters are over-used. For a small system which is fully controlled by you, direct access may be the way to go.
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.