I'm trying to understand the this keyword in java. I wanted to rewrite this code by using the this keyword instead. Please let me know if I've done it right. Here's the original code:
public class Book {
private String title;
private String author;
private String publisher;
public Book(String bookTitle, String authorName, String publisherName){
title = bookTitle;
author = authorName;
publisher = publisherName;
}
}
And here's the re-written code:
public class Book {
private String title;
private String author;
private String publisher;
public Book(String title, String author, String publisher){
this.title = title;
this.author = author;
this.publisher = publisher;
}
}
Have I done it correctly?
Thanks,
Kevin
EDIT: Thanks for the responses... one more question: in the constructor of the revised code, which side of the equals sign refers to the class variables? For example, in this.title = title;, does this.title refer to the title variable from the constructor or from the class variable?
Based on the responses below, I think the answer is this.title refers to the class variable title.
Yes. The this keyword means "the instance of this class that I'm running inside right now". You usually don't need it for variable or method references, but in this (common) case where the constructor parameters have the same name as the fields they're being saved in, using this distinguishes to the compiler between the fields and the parameters.
You've used this correctly.
Now, to understand why this works this way notice that the local variable (constructor parameter) names in your previous version of the constructor are different than your class member names. Hence, this wasn't required since there wasn't any ambiguity.
In the second version, since, their names are the same the constructor parameters over shadow or hide the class member fields within the constructor body. Hence, this which points to the current object instance is required to refer to them explicitly.
Also note that this cannot be used from a static context (block or a static method) for the obvious reason that no current object instance is associated with it. It must be used from inside a constructor, instance block or an instance method.
From HERE
The most common reason for using the this keyword is because a field
is shadowed by a method or constructor parameter.
Lets take an example which illustrates what above statement means. I have added comments at appropriate section of code for your reference.
public class ThisKeywordExample {
private int x;
private int y;
public void setVar(int x, int y) {
x = x; // Setting private variable x value
y = y; // Setting private variable y value
System.out.println(x + " " + y); // prints 10 20
}
public static void main(String[] args) {
ThisKeywordExample obj1 = new ThisKeywordExample();
obj1.setVar(10, 20);
System.out.println(obj1.x + " " + obj1.y); //prints 0 0 because the effect is limited to the local copies of x & y in the setVar method
}
}
Now I would suggest you change setVar method to
public void setVar(int x, int y) {
this.x = x; // Setting private variable x value
this.y = y; // Setting private variable y value
System.out.println(x + " " + y); // prints 10 20
}
and see how it works now.
"this" allows you to easily distinguish between variables of the same name within a class/object.
It appears to me that you have used "this" correctly.
I would, however, caution from using the same variable names for multiple uses. In this situation, it is acceptable; however it would be wise to avoid getting into bad programming habits.
Yes you have understood this in java correctly. From Sun's original documentation:
Within an instance method or a constructor, this is a reference to the
current object — the object whose method or constructor is being
called. You can refer to any member of the current object from within
an instance method or a constructor by using this.
Source: http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
look in your Question there are two big concepts of using this has evolved.
In the 1ST and foremost case this is used to refer to the current object which has evolved that constructor means this carry a referenceid of current object....
In the 2nd case this is used primarly to distinguish between the local parameters and instance variables because the name of both variables types are same....and it is a rule in java that local variable overshadow the instance variables(of same name) when used in any local block or method...so here this differentiates between the instance variable(this.title) and local variable(title)..
And remember this lets u refer directly to the object you can use it to avoid any name space collisions that may ocuur between instance and local variables...
Related
This question already has answers here:
When should I use "this" in a class?
(17 answers)
Closed 2 years ago.
I'm very new to JAVA and trying the following code to initialize the values of object variable using constructor:
public class Javaprog {
int rollnumber;
String name;
Javaprog(int rollnumber, String name) {
rollnumber = rollnumber;
name = name;
}
public static void main(String[] args) {
Javaprog student1 = new Javaprog(12, "Simon");
System.out.println(student1.rollnumber);
System.out.println(student1.name);
}
}
I want to understand why the code above returns the default values of rollnumber and name(0 and null), unless I use "this" to reference the variables inside the constructor like below:
this.rollnumber = rollnumber;
this.name = name;
I'm aware this refers to the current object, but my point is when the constructor runs for creation of an object, does it not understand by default that these variables relate to the object being created .
Is it that, without the use of this keyword they are just "class variables" and don't attach to the object being created.
Found a similar Q here, but did not fully understand the mandate to use this:
java this keyword inside constructor
let’s keep constructors aside and just look at it from a code point of view.
the parameters rollnumber and name are local variables, their scope is only in the function. So when you say
rollnumber = rollnumber;
It simply assigns the current value of local variable rollnumber to itself (does nothing). There is no way to differentiate rollnumber (the parameter/loca variable inside the function) and the instance variable, rollnumber.
To make sure the compiler understands what we want, we use
this.rollnumber (referring to instance variable) = rollnumber (parameter);
To avoid this, you can name your instance variable something else, like rollnum. This way the compiler will search for rollnum in the local scope (meaning within the constructor function, not found) then in the higher scope, where it will be found as an instance variable and correctly assigned.
rollnum = rollnumber;
will work.
Hi all,
I would like to ask you for help to understand logic of this program specially some parts that I am probably stack in.
1.Method ranking(). It doesn´t accept any parametr but returns result from parametrs "won" and "tied". OK. But when we call this method like this
System.out.println(adelaideCrows.getName()+": result:
"+**adelaideCrows.ranking()**);
how the program knows values of "won" and "tied" for this adealideCrows team? I know that OOP is about passing objects respective references to objects. So does it work so that when we firstly call method adelaideCrows.matchResult(ohioFotlball, 1,0); then adelaideCrows is the reference to method matchResult passing there parametres in brackets and then they are stored in memory under reference of adelaideCrows? so when we next call the same method with another reference melbournSoccer.matchResult(newyorkSoccer,6,4); then parametres "won" and "tied" have their own values passed in brackets under reference melbournSoccer? So after calling method ranking() with reference e.g. adelaideCrows program knows that under this reference there are already stored values of parametres "won" and "tied" and method then returns correct values. Right?
2.And also here System.out.println(melbournSoccer.compareTo(newyorkSoccer)); Does the logic is the same? melbournSoccer reference is connected in method public int compareTo(Team<T> team) to this.ranking() but reference newyorkSoccer is connected to team.ranking()? So calling this.ranking() invokes values stored in memory of reference melbournSoccer and so on?
Thank A LOT.
Here is the code for Main class:
public class Main
{
public static void main(String[] args) {
SoccerPlayer soccerPlayer = new SoccerPlayer("joe");
BaseballPlayer baseballPlayer = new BaseballPlayer("pat");
FootballPlayer footballPlayer = new FootballPlayer("backham");
Team<FootballPlayer> adelaideCrows = new Team<>("Adelaide Crows
footbal");
Team<SoccerPlayer> melbournSoccer = new Team<>("Melbourn soccer");
Team<BaseballPlayer> jerseeBaseball = new Team<>("Jersee
Baseball");
melbournSoccer.addPlayer(soccerPlayer);
jerseeBaseball.addPlayer(baseballPlayer);
adelaideCrows.matchResult(ohioFotlball, 1,0);
melbournSoccer.matchResult(newyorkSoccer,6,4);
System.out.println("Ranking...");
System.out.println(adelaideCrows.getName()+": result:
"+adelaideCrows.ranking());
System.out.println(melbournSoccer.getName()+": result:
"+melbournSoccer.ranking());
System.out.println(jerseeBaseball.getName()+": result:
"+jerseeBaseball.ranking());
System.out.println(melbournSoccer.compareTo(newyorkSoccer));
System.out.println(adelaideCrows.compareTo(ohioFotlball));
Player class here from which another three classes FotballPlayer, SoccerrPlayer and BaseballPlayer inherits.
public abstract class Player{
private String name;
public Player(String name){
this.name = name;
}
public String getName(){
return name;
}
}
And here is Team class.
import java.util.ArrayList;
public class Team<T extends Player> implements Comparable<Team<T>>{
private String name;
int played = 0;
int lost = 0;
int won = 0;
int tied = 0;
private ArrayList<T> members = new ArrayList<>();
public Team(String name){
this.name = name;
}
public String getName(){
return name;
}
public boolean addPlayer(T player){
if(members.contains(player)){
System.out.println(player.getName()+" is already on this
team.");
return false;
}else{
members.add(player);
System.out.println(player.getName()+" has been added to team
"+this.name);
return true;
}
}
public int numPlayers(){
return this.members.size();
}
public void matchResult(Team<T> oponent, int ourScore, int theirScore){
if(ourScore > theirScore){
won++;
}else if(ourScore == theirScore){
tied++;
}else{
lost++;
}
played++;
if(oponent != null){
oponent.matchResult(null, theirScore, ourScore);
}
}
public int ranking(){
return (won * 2) + tied;
}
#Override
public int compareTo(Team<T> team){
if(this.ranking() > team.ranking()){
return -1;
} else if(this.ranking() < team.ranking()){
return 1;
}
else{
return 0;
}
}
}
Here are some clarifications to the questions.
Question 1:
Method ranking(). It doesn´t accept any parametr but returns result
from parametrs "won" and "tied". OK. But when we call this method like
this:
System.out.println(adelaideCrows.getName() + ": result: " + **adelaideCrows.ranking()**);
how the program knows values of "won" and "tied" for this
adealideCrows team? ...
Answer 1:
Consider this statement in the Main class: adelaideCrows.matchResult(ohioFotlball, 1, 0);. When this statement executes:
The adelaideCrows object gets affected. In the matchResult method the
instance variables won and tied are changed based on the method input
parameters (1 and 0, in this case).
When the statement adelaideCrows.ranking() is executed, the ranking() method uses the adelaideCrows's object instance variables won and tied (which were set earlier) to calculate the ranking ((won * 2) + tied) and return the value.
NOTES: See this article (my answer) on StackOverflow to get an idea about a Java class, an object, a reference, and class's attributes and behavior: Object References in Java.
Question 2:
And also here
System.out.println(melbournSoccer.compareTo(newyorkSoccer)); Does the
logic is the same? melbournSoccer reference is connected in method
public int compareTo(Team<T> team) to this.ranking() but reference
newyorkSoccer is connected to team.ranking()? So calling
this.ranking() invokes values stored in memory of reference
melbournSoccer and so on?
Answer 2:
Consider the statement: System.out.println(melbournSoccer.compareTo(newyorkSoccer));
Q). melbournSoccer reference is connected in method public int compareTo(Team<T> team) to this.ranking()
A). The keyword this refers to the current object - here it is melbournSoccer. this.ranking method gets the ranking for the melbournSoccer.
Q). Reference newyorkSoccer is connected to team.ranking()?
A). The method parameter compareTo() takes a Team as input - here it is a newyorkSoccer team object.
Q). So calling this.ranking() invokes values stored in memory of reference melbournSoccer and so on?
A). YES.
NOTES: Here is a link to Oracle's Java tutorials topic Using the this Keyword.
I try to answer your first question: The variables „won“ and „tied“ are instance variables. That means every time you create an object of your team class, the object gets its own „won“ and „tied“ variable to save data in it. You can access them with the name of the unique object (in your case the team name as example „adelaideCrows.won“ without the quotes). To answer the question about the „matchResult“ function: The function is related to your object again because you are not using „static“ declaration in front of the method name. So without static every instance of your class gets their own method so if you are passing parameters to that function they are passed into the objects function. If you want to save them you have to create a class variable (which is made with „static int“ as example) or a instance variable in order to save the data as long as the object exists, otherwise the data will get passed to the function and will be lost after the function execution is finished.
I have two classes. Both of them refer to the same variables inside the constructor. I am confused, when I used this.name I don't need to change the name of the parameter, the Java compiler knows that I am referring to the main variable?
On the second class example, the parameters name was changed but it is not using this.
What is the different between these two classes?
Are they both considred "good programming" ?
class Account {
private string name;
private int amount;
Account(String name, int amount) {
this.name = name;
this.amount = amount;
}
}
class Account {
private string name;
private int amount;
Account(String n, int a) {
name = n;
amount = a;
}
}
In this case Account(String name, int amount) if your code says name = "ABC";, it is setting the parameter name, not the member. If you want to set the member, you need you reference it via this.name.
So name = name; does nothing (sets the parameter to itself). this.name = name; sets the member to the parameter.
Both of your codes are not wrong.! But, In Java it's considered poor practice to use meaningless name prefixes or suffixes to distinguish instance variables from parameters from local variables. I would like to recommend to use whatever names make the code easiest to understand.
Java allows to use same name for instance variable and local variable/parameter.
When method/constructor parameter name is same as instance variable name then we need to explicitly use this keyword to inform JVM that we are trying to use this instance variable; not local variable. Otherwise, for same named variables without this JVM selects more specific scope variable.
For first case you are using same variable name for parameter and instance variable called name so you need to explicitly define which one is your instance variable using this as bellow:
this.name = name;
For second case, there is no naming confusion so if you don't use this there is no problem to identify instance variable.
N.B.
It is better to use this for readability when you are accessing instance variables.
Either are fine. You would only use this.name if you wanted the private instance variable to also be called name. When you have an instance variable that is a different name than the parameter taken in, it does not matter.
What's the different between this two classes?
Functionally none. Compiler will change your 2nd example as follows:
Account(String n, int a)
{
this.name = n;
this.amount = a;
}
Are both ways consider "good programming"?
I prefer 1st way to write code.
This question already has answers here:
How to avoid constructor code redundancy in Java?
(4 answers)
Closed 9 years ago.
Hi I am just learning about constructor chaining in Java and had some questions...
First of all could someone please explain when I would ever need to use this? Off the top of my head I seriously cannot think of a situation.
In this example, within the constructor with no arguments I call another constructor. How do I access this new "James Bond" object for future use?
import java.util.*;
class Employee
{
private String name;
private double salary;
public Employee()
{
this("James Bond", 34000);
}
public Employee(String n, double s)
{
name = n;
salary = s;
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public static void main(String[] args)
{
Employee a = new Employee();
}
}
Actually I believe the most common use of chained Constructors is when the Constructor does more than just setting the member variables.
static int numOfExamples = 0;
public Example(String name, int num)
{
this.name = name;
this.num = num;
numOfExamples++;
System.out.println("Constructor called.");
Log.info("Constructor called");
}
public Example()
{
this("James Bond",3);
}
That way we don't have to write the code for logging and incrementing the static variable twice, instead just chaining the constructors.
Chaining constructors like this is useful to avoid repeating code, and helps with maintainability:
public MyClass(int x, double y, String z) {
// set fields
}
public MyClass() { // i.e. a constructor that uses default values
this(42, 4.2, "hello world"); // x is 42, y is 4.2, and z is "hello world"
}
If we didn't use the chain, and wanted to change how the x argument (for example) is processed when constructing an instance of MyClass, we would have to change code in both constructors. With the chain, we only need to change one of them.
1) As others have said, it's for code maintenance, basically the idea is that you only write one piece of code once, which means you only need to edit it once, there is no risk of overlooking something when editing your methods and the two accidentally becoming different.
Personally I tend to use this differently than in your example. Like so:
Employee() {
setupStuff();
}
Employee(String name) {
this();
this.setName(name);
}
This is a nice way of doing things, because potentially your setter can be way more complicated than just setting a member in the class. So basically what this does is puts calling the empty constructor and then a setter into a single method, making it much easier for anyone using the class.
2) The constructor being called doesnt't create a different object at all, it creates this object. Note that there is no new keyword used. Basically you're just calling a different method inside your constructor, except that method happens to also be a constructor.
Every time you want to allow constructing an object wit default values, and also want to allow creating the same object with non-default values. Let's imagine a DateTime class. You could want to initialize it with the current time by default, or with a specific time. Imagine a Car class. You could imagine constructing it with Black as the default color, or with a specific color. This kind of situation is very common. See java.util.ArrayList or java.util.Locale, for concrete examples.
It's stored in the name field. So you access it, from the object itself, with this.name (this being optional, just as in the getName() method).
How do I access this new "James Bond" object for future use?
Because you saved the values of name and salary as fields of your employee class, then inside the employee class you can use those fields, and outside your employee class you can use the getter/setter methos of your employee class
I have a question regarding this in the following code. In the following, this.name will set the name. We could also do this using name = name, so my question is should the this pointer be used. This is not an homework
import java.io.*;
public class Employee{
String name;
int age;
String designation;
double salary;
//This is the constructor of the class Employee
public Employee(final String name){ //EDIT: Made parameter final
this.name = name;
//name= name; this is also correct
}
//Assign the age of the Employee to the variable age.
public void empAge(int empAge){
age = empAge;
}
//Assign the designation to the variable designation.
public void empDesignation(String empDesig){
designation = empDesig;
}
//Assign the salary to the variable salary.
public void empSalary(double empSalary){
salary = empSalary;
}
//Print the Employee details
public void printEmployee(){
System.out.println("Name:"+ name );
System.out.println("Age:" + age );
System.out.println("Designation:" + designation );
System.out.println("Salary:" + salary);
}
}
// name= name; this is also correct
This is not correct. It'll assign your parameter to itself. By using the this keyword, you're declaring which name you're using (i.e. the field on your Employee object).
You may wish to name the field differently from the parameter. However this means that all works well until someone automatically refactors your code to (perhaps inadvertently) declare the field and parameter as the same name!
For this reason you'll often see method signatures defined thus:
public Employee(final String name)
The final keyword prevents reassignment, and stops you from mistakenly reassigning the input parameter, and consequently not assigning to your field. Note also that if you declare the field as final, then compilation will fail if you don't make an assignment to that field. Using final is a good way to trap such errors and also enforce the immutability of an object (often a good thing - it contributes to a more reliable solution, especially in a threaded environment).
Well to avoid the confusion in cases like u mentioned name=name we uses this pointer to make it clear the we here mean class variable name .
So to make understand the reader here in this case we use this though there can be many other cases where (this) is more useful.
In some compilers name=name gives error as well
Notice that there are two things called name in your code. Your class Employee has member variable called name, and the constructor takes a parameter that's also called name.
What you want to do in the constructor is set the member variable name to the same value as the parameter name. To access the member variable, you have to use this.name, because name refers to the parameter - because the variables have the same name, the parameter is hiding the member variable.
Note that name = name; does not do the same thing as this.name = name;.
When you do name = name;, you assign the value of the parameter name to the parameter itself - not to the member variable. The compiler does not magically know that the first name is supposed to mean the member variable, and the second name is supposed to mean the parameter.
So, you need this in this case to refer explicitly to the member variable, instead of the parameter that is hiding the member variable.
In this case this is just a scope resolution/disambiguation.
public Employee(String name){
this.name = name;
// the above line will assign a value of parameter to instance variable
// name= name; this is also correct
// (**NO** the above line will assign a value of parameter to itself)
}
When the parameter name and your class variable names are same, then to differentiate between them, you write this.classVariable to identify the class variale
When you call a variable, the pointing one is the one who is the closest to your current scope.
So, if program is currently containing in memory a local variable toto and the wrapping class containing a field variable toto, you have to precise this keyword in order to access the field's one.
Otherwise, the field variable is said to be shadowed by the local variable and so doing toto = toto assigns the local parameter to itself (never useful) and not what you are expecting => the field variable.
Why make it so hard on yourself?
Just rewrite the signature/method like this:
public Employee(String _name) {
name = _name;
}
Always try to avoid variable hiding or other hard-to-read constructs. If you want your code to be maintainable, write it in such a way that everybody can understand it immediately. Even if you are the only one; you might forget what you meant in time.
This Keyword Program
public class ThisKeywordActivity extends Activity {
int a=20;
public ThisKeywordActivity(int a) { // this();
//this.a = a;
}
public ThisKeywordActivity()
{
System.out.println(" msg default Constructor ");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_this_keyword);
ThisKeywordActivity thisKeywordActivity2 = new ThisKeywordActivity(100);
thisKeywordActivity2.show(40);
}
public void show( int a)
{
System.out.println("msg a 2==="+a);
System.out.println("msg a 3==="+this.a);
}
}
Output
a2=40
a3=20