Why dont we use 'this' in getters? [duplicate] - java

This question already has answers here:
When should I use "this" in a class?
(17 answers)
Closed 5 years ago.
For instance, lets say that we have an object called car which is a part of Cars class and it has a color property. And assuming that we have a getter for the color such that:
public String getColor(){
return color;
}
But should not it be this.color? If not, why?

You use this implicitly here. When you "leave" out the object on which you "access" a field or call a method ... then that is the same as saying this.field or this.foo() Unless of course, that the name you are using refers to a local variable for example. So, just to be precise: when you have code such as
void setter(Whatever foo) {
this.foo = foo;
then of course you have to use this in order to differentiate between the field foo and the local variable foo that is shadowing that field.
Any slightly experienced Java programmer knows that. Therefore it is good practice to not write down this here. Keep in mind: you write your code so that your human readers understand what is going on. The compiler and IDEs are fine with using this ... or not using this. But for your human readers it simply means a little bit less of information to process when you leave out this keyword here.
That is all there is to this.

'this' always represents current object. SO if you say this.color it's excatly same as simply say 'color'. You can doesn't mean you should :)

It's superfluous. In general you use the this.something only if you have a parameter in the method's signature with the same name. Classical example are constructors:
public MyClass(String val1, String val2) {
this.val1 = val1;
this.val2 = val2;
}
It was used more often in the past when there was no syntax highlighting in IDEs that included the different presentation of member and local variables. Then this was used to make it easier to distinguish between these two types of variables.

Related

How to define a "good" get() method for a private variable in a class? [duplicate]

This question already has answers here:
Why make defensive copies in getters inside immutable classes?
(7 answers)
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 3 years ago.
I'm learning Java and I have some doubts.
If defined a class with a private variable like
class test<A>{
private A var;
...
public A get(){
return var;
}
}
Is the get method wrong?
I think so because with this definition I can modify the variable "var" like
test<A> x = new test<A>();
A temp = x.get();
temp.set(*something*);
At the end x is changed (I tested it using Vector as A). If I understand correctly, this works because object reference (I miss C pointers, sob). Am I wrong? Maybe I don't understand the purpose of the keyword "private"! Thanks in advance!
Edit: I have no problems with "pass-by-reference" and "pass-by-value". I have doubts defining get() method for a private variable in a class (you don't say?). Please stop linking Is Java "pass-by-reference" or "pass-by-value"?
If your getter method is returning a reference to a mutable object, then this greatly weakens the quality of the encapsulation provided by your class, because it becomes possible to modify the state of an instance of your class without calling a method of the class.
One standard strategy to guard against this problem is what J. Bloch calls defensive copies (Effective Java, 3rd edition, Item 50: "Make defensive copies when needed").
This would mean creating a copy of var in the getter method, and returning that copy instead. How to do this depends on the design of A.
Because A is a type parameter, making a copy of the instance requires additional support in the design. To see how to achieve this using Java's cloning mechanism, see my answer to the post "Does it make sense to create a Copyable type interface instead of using Cloneable?".
If this is a problem, you can create a façade to protect your variable
public class Facade extends A {
A myObj;
public Facade (A obj) {
myObj =
}
public A get(){
return myObj.get();
}
public B set(Object val) {
throw new RuntimeException("Setting is not allowed");
}
}
This might be a bit too much detail for just starting, but you might review class java.util.concurrent.atomic.AtomicReference<V>, which is very similar to your example.
Generally speaking, placing instance variables in private variables, while providing access to the variable using a getter and a setter, is standard practice.
Note that your class name should be capitalized, type parameter 'V' is more standard, and the variable name would more usually be 'value'. Also, try to pick a more communicative name for the class. (Type parameter type variable could be 'ValueType', which would fit some preferences. But, single character type variable names are more usual.)
public class Wrapper<V> {
private V value;
public V get() {
return value;
}
public void set(V value) {
this.value = value;
}
}
I'd add some other point here: as others have said, you hand out the object reference and it can be modified, which could be bad.
Object orientation is about keeping the data and the code that works on it in one place. If you need getters, think what the callers of the getters need to do, and whether that action should rather be a method on the class that has the data. Your code could suffer from the Feature Envy code smell, as it violates the Tell, Don't Ask principle.
To fix this, remove the getter, and introduce new methods as needed. For example, if you have some data object that needs to get printed, you could pass the Printer to the object and have it print itself to the given Printer.
If you're dealing with a collection class (just a guess from your template parameter), you may need to keep the getter, but then you're probably not concerned with the caller changing the value anyway.

Is this considered reflection?

I had a job interview today and I was asked, if the code below is a good example/case of using reflection in C#:
public abstract class Level{
public string LevelID { get; private set;}
public int LevelNumber {
get{
return int.Parse(LevelID.Substring(5).ToString());
}
}
public Level(){
this.LevelID = GetType().ToString();
}
}
I assume the use of the code above would be:
class Level32 : Level{
// call base class constructor...
}
and then
Level32 level = new Level32();
int id = level.LevelNumber; // would print 32.
I think the guy meant this line: this.LevelID = GetType().ToString();
I said that there's no reflection at all.
As good as I know Java, calling SomeClass.class.getName() does not use any of the 'reflective' packages, so it doesn't use reflection at all. I thought that C# is built that way too.
Am I dumb, or he is?
I think that, strictly speaking, the GetType() call is reflection, yes.
See https://stackoverflow.com/a/24377353/8261
However, it is only the most trivial reflection, so I wouldn't think you were "a "Hello World" kid" for discounting it. :-)
Am I dumb, or he is?
I don't like this framing: it seems to me that neither of you are (or perhaps both of you are, for getting into an argument over trivial semantics).
First sentences from Microsoft docs:
Reflection provides objects (of type Type) that describe assemblies, modules and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object
Method GetType() returns object of type Type and is used (obviously) to "get the type from an existing object". Looking only at those rules we can say it is reflection.
To be clear, I consider this a bad question for interview, there a better ways to check if candidate understands reflection.
I don't have 50 reputations to add comments. Please don't mind me adding it as an answer. :)
We already have a few good answers about GetType().
I'd like to answer "is a good example/case of using reflection?".
I think the intended answer is "No".
The keywords here are abstract and GetType(). The point of creating abstract classes and interfaces is that the caller doesn't have to know what the exact type it is.
If we still have to know the actual type of the sub-classes, we're not using it correctly.
So I think this is not really a question about reflection. It's more like a question about OOP/inheritance.
That's just my 2 cents.

Is it a good practice to use keyword "this" to access instance function or members? [duplicate]

This question already has answers here:
When should I use "this" in a class?
(17 answers)
Closed 9 years ago.
So I know how useful keyword this is in constructor, when class member and parameter uses the same name.
Do people commonly use this outside of constructor to access instance variable/member and function? Is this a good practice? Should I keep using this keyword or should I not use it?
class Test {
private int num = 0;
Test(int num) {
this.num = num;
}
public int getNum() {
return this.num; // I could write num;
}
public void doSomething() {
System.out.println(this.getNum()); // I could have just invoked getNum()
}
}
First and foremost, It's a matter of personal (or team) style. Some developers think it contributes to readability, some find it redundant and cumbersome.
Having that said, I think it's a good idea to use this because it prevents confusion between different scopes.
If this is always used, the developer who inspects a part of the code doesn't have to scroll up every time a variable is referenced just to find out what's its scope.
When working in a team the most important thing might be that all members use the same style, e.g. formatting, camelCase or mCamelCase for names and even using this keyword everywhere.
Nothing is less readable than code using different styles.
Every project you are in might have a different style, but all members should adhere to the rules.
Just be flexible.
Try to generate getters in eclipse.. Even eclipse will use this keyword outside the constructor ;) So, yes it is commonly used and very habitual practise.
Yes, you can do this.your_field. There is no problem using the this keyword.
You only have to use it if otherwise you'd be referring to an entirely different variable/method.
In your constructor above for instance, if you hadn't used it, you'd be referring to the parameter passed to the constructor.
In your doSomething() method there was no need for the this keyword.

Set, Get and Constructors in Java

Despite Java tutorials, Wikipedia searches, stackoverflow trolling, and hours of reading code samples, constructors still confuse the crap out of me. I've got three related questions that I've been trying to answer to help ME understand constructors a little better.
First, I've been under the impression that constructors need to be named the same as their classes. Consider:
public class Money {
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
public long getLong() {
return this.value;
}
public String getString() {
return toString(this.value);
}
}
I see this as four constructors...correct? So it appears that constructors not named the same as the class which contains them allowable. Can someone confirm that?
Second, I seem to have a block against understanding the set and get methods. Consider:
public class GetSetSample {
public int getFoo() {
return int Foo;
}
public void setFoo(int fooValue) {
int Foo = fooValue;
}
}
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
and use foo = getFoo(12) from some other class/method?
The third question is a little more esoteric, but will help me conceive of the bigger picture...which is my learning style, and conducive to my ability to trace program flow when debugging. The get and set methods suggest a "to" and "from" relationship to me. e.g., Passing a value "to" a constructor, receiving the result "from" the get method. It seems to me though that the "to" and "from" will change depending on your perspective. I think that any setMethod is setting parameters for an object, even though the variable comes FROM another class or method, and the GetMethod is getting the resulting object (say, this.foo) with the appropriately set parameter. No matter where the get or set is used, in a main method or a standalone class with a single constructor, 'set' is always associated with sending a parameter and get is always associated with receiving an object with that parameter. Is that a good understanding? or am I missing a vital part?
Question 1:
I see this as four constructors...correct?
No, that class has two constructors and two methods. (getLong and getString are the methods.)
Question 2:
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
Well, that's trying to declare a class with parameters, and also you're setting a value in a get method, which would be extremely weird. It's not clear what you're trying to achieve here, but that code is thoroughly invalid.
Question 3:
The get and set methods suggest a "to" and "from" relationship to me.
Well it's not really a relationship IMO. A relationship suggests something longer term than either of these methods. A setter typically changes the state of an object in some way, and a getter typically just returns some aspect of the state of an object. It's not really clear what the rest of your explanation meant, because you're playing somewhat fast and loose with terminology. For example: "get is always associated with receiving an object with that parameter" doesn't really make sense to me. Objects don't have parameters, methods/constructors do - and getters can fetch primitive values or references...
I suspect you would benefit from reading the "Classes" part of the Java tutorial, which talks about constructors and methods.
Regarding the first answer, there's only 2 constructors. The difference is on how they are going to be called (called using a string will use the construction having a string has a parameter and called using a long will use the other one). So to answer, yes a constructor has the same name as the class.
The two constructors :
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
Regarding the second answer, getters ans setters are not meant to be classes. They are supposed to be within the class itself.
Consider this example which uses getter and setters to get ans set value for the printer class :
public class Printer {
#Inject #Informal Greeting greeting;
private String name;
private String salutation;
public void createSalutation() {
this.salutation = greeting.greet(name);
}
public String getSalutation() {
return salutation;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
A good read of this link could definitly help you out !
Java oriented-object principles
You've shown 2 constructors, which do need to have the same name as the class.
You've also shown two "getter" methods, which return the value of the class variable in the form requested by the user. You can also create "setter" methods, which are used to transfer values into class variables.
You use a constructor to create an object of a particular class, and optionally to set some or all of its internal state (that is, its member variables).
You use setters and getters to isolate the class variables from the outside world, so you don't need to allow other code to access them directly. Why? Because, before a setter updates a variable, it can verify that the new value is valid, and that the operation doesn't violate any or the rules (the "business logic") that are required for the class to work properly.
So you could add a setter and update the constructor to use it:
public Money(long l) {
setValue(l);
}
public Money(String s) {
setValue(toLong(s));
}
// Example setter that validates `l` by prohibiting negative values
public Money setValue(long l) {
if (l < 0) {
// Warn about negative values
}
this.value = l;
return this; // Return the current object to allow chaining; see below.
}
Note that a setter usually doesn't need to return a value (that is, it can be type void), but it's often helpful to return the object itself. That allows you to write code like this:
Money earnings = new Money().setValue(4).setOtherField("foo");
This creates an object of type Money, sets various attributes, and stores it in the variable earnings. Clearly, this isn't terribly useful for a simple class like this, but it can be very helpful for more complex classes:
Paycheck check = new Paycheck("MyCompany")
.setEmployee("YourName")
.setSalary(50,000)
.setPaySchedule(Schedule.BIWEEKLY)
.setAccountNumber("1234567")
.setDefaultTaxRate();
I would like to try to answer your implied conceptual questions -- you've already got plenty of examples of this and that, so I'm just going to try to explain. I have no doubt you have heard most of this -- maybe all of this -- before, but am not sure and not sure which parts.
Object-oriented programming centers mostly around objects; an object is an amalgamation of code and data. You define objects by writing a class, and you create one or more copies of the object defined by that class with the class constructor (called instantiating the class).
A parallel in other languages: you can have a data structure of related items and a set of subroutines that operate on that data structure. Think of a class as a way of collecting the items in that data structure and the subroutines that operate on it into one unit.
After you have invoked a constructor, you have a copy of the data defined in that class and a way to refer to that copy. By referring to that instance when you invoke a class method, you operate on that copy of the data with the methods defined in that class.
If you were to do this in a non-OO language, you could have a routine that created a copy of the data structure in memory and then only use the methods prescribed for it on that data structure. You could have a pointer to the copy in memory and pass that pointer as a parameter to every subroutine that operated on it, and in fact that's the way some pre-OO systems were programmed.
A constructor is similar to a method call that returns a value; it involves (or can involve) the execution of statements, and it always returns an object of that class. There are also differences between a constructor and a method; until the constructor completes, for instance, the object is not fully created and shouldn't have some methods invoked on it.
So I hope that helped; if there are conceptual things you still have questions about, perhaps something in here will help you form a specific question so we can explain things further.
Many people have found that if they have spent years learning languages such as COBOL and FORTRAN then changing to OO programming involves unlearning the old languages. I certainly found this when I first tackled C++ 20 years ago. From your description you are clearly struggling with the concepts and I sympathize.
I don't think there is a simple recipe. Practice at the simple examples and don't be disheartened. Don't be afraid to ask on SO - if the questions are clearly asked you will get a useful answer.
Get a good IDE (Eclipse, Netbeans, etc.) which allows you to "look inside" objects with the debugger. Hopefully at some stage things will click!
Question 1 - Basic Java Classes:
There's pretty much only 3 things you're going to find in a Java class
Field/attribute (Depending on your language of origin)
Method
Constructor (Which looks like a special kind of method)
Every class is going to have a class name that shares the name of the file it's located in. So to expand Money out a bit:
Money.java
----------
public class Money {
// This is a field/attribute
Long value;
// This is a constructor
public Money() {
this.value = Long(0L);
}
// This is a method
public Long getValue() {
return value;
}
// Another method
public void makeMoney(Long moreMoney) {
this.value = this.value + moreMoney;
}
} // Everything in here is part of the Money class
The only distinction between a constructor and a method is that a constructor has no specified return value, which is declared as a type right before the name of a potential method. Constructors do have to be named the same as the class they are contained in, but why is implied in how they are written.
Another way of looking at it is if you remove all of the non-type related Java keywords (public, private etc., but not things like float and int) from the front of the method you're looking at (A list of which you can find here), is there anything left in front of the method?
With the Money we have at the moment, it would look like this:
Money()
Long getValue()
void makeMoney()
The constructor is the one that has no type for the return value, because it is implied in the declaration.
Question 2/3 - Get/Set methods:
I'm going to say something potentially controversial, but don't worry about these yet. Get/Set are essentially patterns for Object Oriented development, and generally good Java style, but they aren't required (Last I checked, Android development actually discourages their use when possible for optimization reasons). Moreover, not all fields in your objects will be accessible or mutable so writing them isn't mandatory.
If you declare all of your fields as public (Like the 'value' field is implied to be right now), you simple can do this:
Money myMoney = new Money(new Long(40L));
System.out.println(myMoney.value) // 40
myMoney.value = new Long(20L);
System.out.println(myMoney.value) // 20
Aside from that, the notion of get() and set() are just methods. There is nothing special about them at all. The main reason they exist is because for general Object-Oriented programming, you shouldn't have to directly modify the internal workings of an object (This is the principle of Encapsulation). Everything you should need to affect state or get something out of it should be handled by a method.
In a pithy one-liner: If you need to know the fields of an object to use it, you designed it incorrectly.
Big Picture
So what get() and set() really are is a pair of commonly written methods that happen to affect a field in an object in an extremely simple way (get() is a simple access to a field, set() is assignment to that field). It's just that other methods you write will happen to do more complicated stuff than that.

What is a good practice to access class attributes in class methods?

I always wonder about the best way to access a class attribute from a class method in Java.
Could you quickly convince me about which one of the 3 solutions below (or a totally different one :P) is a good practice?
public class Test {
String a;
public String getA(){
return this.a;
}
public setA(String a){
this.a = a;
}
// Using Getter
public void display(){
// Solution 1
System.out.println(this.a);
// Solution 2
System.out.println(getA());
// Solution 3
System.out.println(this.getA());
}
// Using Setter
public void myMethod(String b, String c){
// Solution 1
this.a = b + c;
// Solution 2
setA(b + c);
// Solution 3
this.setA(b + c);
}
}
That entirely depends on what the getters and setters are doing. If they do more than just getting and setting the value (which should be explicitly documented in the method's Javadoc), then it would really make difference what way you'd choose from inside the class. But if they are pure Javabean like getters/setters, then I'd rather access the variable directly by either a or this.a depending on whether there's a local variable in the scope with exactly that name.
Personally I would just keep the getters and setters "pure" according the Javabean spec and add another getter or setter with a self-explaining method name whenever I'd like to do something more than just getting/setting the value. E.g. getAndIncrement(), getAsString(), setAsInt(String), etc.
Matter of taste. It won't really harm as long as you're consistent with it throughout your coding.
If you need to create any validation in the future you'll want a setter/getter . When you make a variable visible you brake the class encapsulation. In theory it means that your code is not so Object Oriented :P , but in practice you lose the ability to do a lot of code refactorings. For example, extracting a interface.
And for the this call, I think its redundant, but that's just me :)
I use getters and setters in a class if there is more logic involved that just returning this.value. This way I avoid duplication. An example:
...
public List<String> getList() {
if (this.list == null) {
this.list = new LinkedList<String>();
}
return this.list;
}
public int getListSize() {
return getList().size();
}
...
I always use "this" because it makes it easier for other people to read my code. There is no doubt that this.value is a class attribute, whereas value can be both a local variable and a class attribute.
Solution 2 or 3 are best practice as they provide encapsulation to the field. For example, what if the field 'a' is a user's postcode and your application has a new requirement to always return the postcode as uppercase. With solutions 2 or 3 this becomes trivial. E.g.
private String postcode;
public String getPostcode()
{
return postcode;
}
becomes
private String postcode;
public String getPostcode()
{
return postcode != null? postcode.toUppercase() : null;
}
and you will only have made the change in one place instead of anywhere where the field is accessed. The addition of this is purely up to your own personal style or project standards. Personally, I don't like it as it is unnecessary and just gets in the way of readability, but for others it makes the owner of method/field clearer.
Using setA(b + c) is silly.
Getters and setters are part of the interface. Methods already have full access to the state. Be frank about it.
If you're worried that you might break an invariant then your class is too complex for you. (Admit it and refactor.)
Using getters and setters is the way to go.
It's commonly accepted practise
So other programmers are more likely to understand your code.
It gives the class author options in the future
Say you want to prevent someone setting a to null. Expose the member and you can never do it.
As for whether to use this - I try to use this consistently to make it very clear to anyone else which are instance members and which are local variables at any point - also helps avoid accidental shadowing, but I think this is less important and more a style thing.
Also - this.a is an instance member (one per instance) not a class member (one-per-class, would be static). Another reason to use this to be clear.
I would go with
System.out.println(getA());
and
setA(b + c);
for the simple reason that if you wanted to generally change the way an attribute is accessed or enforce any constraints as to what you could set a variable to, you can just change the getA or setA methods.
I don't like using this unless I need to explicitly distinguish between variables of the same name.

Categories