This question already has answers here:
What is the meaning of "this" in Java?
(22 answers)
Closed 7 years ago.
I was studying method overriding in Java when ai came across the this keyword. After searching much about this on the Internet and other sources, I concluded that thethis keyword is used when the name of an instance variables is same to the constructor function
parameters. Am I right or wrong?
this is an alias or a name for the current instance inside the instance. It is useful for disambiguating instance variables from locals (including parameters), but it can be used by itself to simply refer to member variables and methods, invoke other constructor overloads, or simply to refer to the instance. Some examples of applicable uses (not exhaustive):
class Foo
{
private int bar;
public Foo() {
this(42); // invoke parameterized constructor
}
public Foo(int bar) {
this.bar = bar; // disambiguate
}
public void frob() {
this.baz(); // used "just because"
}
private void baz() {
System.out.println("whatever");
}
}
this keyword can be used for (It cannot be used with static methods):
To get reference of an object through which that method is called within it(instance method).
To avoid field shadowed by a method or constructor parameter.
To invoke constructor of same class.
In case of method overridden, this is used to invoke method of current class.
To make reference to an inner class. e.g ClassName.this
To create an object of inner class e.g enclosingObjectReference.new EnclosedClass
You are right, but this is only a usage scenario, not a definition. The this keyword refers to the "current object". It is mostly used so that an object can pass itself as a parameter to a method of another object.
So, for example, if there is an object called Person, and an object called PersonSaver, and you invoke Person.SaveYourself(), then Person might just do the following: PersonSaver.Save( this );
Now, it just so happens that this can also be used to disambiguate between instance data and parameters to the constructor or to methods, if they happen to be identical.
this keyword have following uses
1.used to refer current class instance variable
class Student{
int id;
String name;
student(int id,String name){
this.id = id;
this.name = name;
}
void display(){System.out.println(id+" "+name);}
public static void main(String args[]){
Student s1 = new Student(111,"Karan");
Student s2 = new Student(222,"Aryan");
s1.display();
s2.display();
}
}
here parameter and instance variable are same that is why we are using this
2.used to invoke current class constructor
class Student{
int id;
String name;
Student (){System.out.println("default constructor is invoked");}
Student(int id,String name){
this ();//it is used to invoked current class constructor.
this.id = id;
this.name = name;
}
void display(){System.out.println(id+" "+name);}
public static void main(String args[]){
Student e1 = new Student(111,"karan");
Student e2 = new Student(222,"Aryan");
e1.display();
e2.display();
}
}
3.this keyword can be used to invoke current class method (implicitly)
4.this can be passed argument in the method call
5.this can be passed argument in the constructor call
6.this can also be used to return the current class instance
This refers current object. If you have class with variables int A and a method xyz part of the class has int A, just to differentiate which 'A' you are referring, you will use this.A. This is one example case only.
public class Test
{
int a;
public void testMethod(int a)
{
this.a = a;
//Here this.a is variable 'a' of this instance. parameter 'a' is parameter.
}
}
Generally the usage of 'this' is reserved for instance variables and methods, not class methods ...
"class methods cannot use the this keyword as there is no instance for
this to refer to..."
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
Here's a trivial example ...
public class Person {
private String name;
private int age;
private double weight;
private String height;
private String gender;
private String race;
public void setName( String name ) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge( int age) {
this.age = age;
}
public int getAge(){
return this.age;
}
public void setWeight( double weight) {
this.weight = weight;
}
public double getWeight() {
return this.weight;
}
public void setHeight( String height ) {
this.height = height;
}
public String getHeight() {
return this.height;
}
public void setGender( String gender) {
this.gender = gender;
}
public String getGender() {
return this.gender;
}
public void setRace( String race) {
this.race = race;
}
public String getRace() {
return this.race;
}
public void displayPerson() {
System.out.println( "This persons name is :" + this.getName() );
System.out.println( "This persons age is :" + this.getAge() );
System.out.println( "This persons weight is :" + this.getWeight() );
System.out.println( "This persons height is :" + this.getHeight() );
System.out.println( "This persons Gender is :" + this.getGender() );
System.out.println( "This persons race is :" + this.getRace() );
}
}
And for an instance of a person ....
public class PersonTest {
public static void main( String... args ) {
Person me = new Person();
me.setName( "My Name" );
me.setAge( 42 );
me.setWeight( 185.00 );
me.setHeight( "6'0" );
me.setGender( "Male" );
me.setRace( "Caucasian" );
me.displayPerson();
}
}
In case of member variable and local variable name conflict, this key word can be used to refer member variable like,
public Loan(String type, double interest){
this.type = type;
this.interest = interest;
}
if you have knowladge about c,c++ or pointers, in that language this is a pointer that points object itself. In java everything is reference. So it is reference to itself in java. One of the needs of this keyword is that:
Think that this is your class
public class MyClass
{
public int myVar;
public int myMethod(int myVar)
{
this.myVar = myVar; // fields is set by parameter
}
}
If there is not this keyword you it is confused that this is paramter or class field.When you use this.myVar it refers field of this object.
I would like to modify your language. The this keyword is used when you need to use class global variable in the constructors.
public class demo{
String name;
public void setName(String name){
this.name = name; //This should be first statement of method.
}
}
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.
One more thing that should be in mind is that this keyword might be the first statement of your method.
This is used in java. We can use in inheritance & also use in method overloading & method overriding. Because the actual parameter or instance variable name has same name then we can used this keyword complsary . But some times this is not same as when we can not use this keyword complsary.....
Eg:- class super
{
int x;
super(int x)
{
this.x=x
}
}
Related
This question already has answers here:
this() and this
(4 answers)
Closed 2 years ago.
package test;
public class Employee {
String name;
int age;
Employee() {}
Employee(String newName, int newAge) {
this();
name = newName;
age = newAge;
}
public static void main(String args[]) {
Employee e = new Employee("N", 43);
System.out.println();
}
}
In the above code, what is the actual point of "this()" in the overloaded constructor from a usefulness perspective besides being an example of calling the no-argument constructor from the overloaded constructor?
This looks like it's the wrong way round to me.
A typical use of this() would be to provide a default value for the constructor when not supplied in the argument as you cannot call the constructor directly. Adapting your code for example:
package test;
public class Employee {
String name;
int age;
Employee() {
this("Default", 42);
}
Employee(String newName, int newAge) {
name = newName;
age = newAge;
}
public static void main(String args[]) {
Employee e = new Employee();
System.out.println();
}
}
In that exact snippet?
Literally nothing.
Any constructor MUST neccessarily have, at the top of it, either a this() call, or a super() call. You can't not. If you fail to write it, javac will inject: super(); for you, and if that isn't valid (for example, your superclass does not have a protected+ no-args constructor), then your code won't compile.
So that's the difference between the snippet as pasted and a hypothetical one where the this(); is removed. Desugaring, you get either:
Desugared, WITHOUT the this():
package test;
public class Employee {
String name;
int age;
Employee() {
super(); // invokes java.lang.Object's no-args, which does nothing.
}
Employee(String newName, int newAge) {
super(); // invokes java.lang.Object's no-args, which does nothing.
name = newName;
age = newAge;
}
}
Desugared, WITH the this():
package test;
public class Employee {
String name;
int age;
Employee() {
super(); // invokes java.lang.Object's no-args, which does nothing.
}
Employee(String newName, int newAge) {
this();
name = newName;
age = newAge;
}
}
Now, inject, say, a System.out.println("Hello!"); in the no-args constructor and now there is a small difference: With the this(), you'd see Hello! printed, and without it, you won't. Either way, though, you end up calling your superclass's constructor, as that is something that has to happen, one way or another. (Only java.lang.Object doesn't have to, hardcoded in the VM; Object has no superclass).
To call the default constructor, this() is used.
I created a new class "Lecturer" which extends another class "Person", i wanted to make 2 constructors for Lecturer and one would accept a name and a stipend (just a constant to say how much pay is), the other just accepts the name and uses the default stipend set in the code. i included appropriate getters and setters. I then wrote a writeOutput method to print an output similar to this
Name: (name) which gets the name and prints it
Stipend: (stipend) same process ^
heres what i have so far
Lecturer.java
public class Lecturer extends Person{
private static String name;
static double stipend;
public Lecturer(String name) {
super(name);
}
public Lecturer(String name, double stipend) {
super(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getStipend() {
return stipend;
}
public void setStipend(double stipend) {
this.stipend = stipend;
}
public static void writeOutput() {
System.out.println("Name: " + name);
System.out.println("Stipend: " + stipend);
}
}
Person.java
public class Person {
/** Every Person has a name */
private String name;
/** Person requires a name */
public Person(String n) {
this.name = n;
}
/** return this Person's name */
public String getName() {
return this.name;
}
/** Change this Person's name */
public void setName(String nn) {
this.name = nn;
}
Main file (Inheritance.java)
Lines 41-53
Lecturer l1 = new Lecturer("Zachary");
Lecturer l2 = new Lecturer("Wilhelmina", 11017.00);
l1.writeOutput();
l2.writeOutput();
pause();
l1.setName("Zack");
l1.setStipend(10800.00);
l1.writeOutput();
pause();
System.out.printf("%s's stipend is $%,4.2f.\n",
l1.getName(), l1.getStipend());
System.out.printf("%s's stipend is $%,4.2f.\n",
l2.getName(), l2.getStipend());
This is the output
Name: null
Stipend: 0.0
Name: null
Stipend: 0.0
press enter...
Name: Zack
Stipend: 10800.0
The 2nd part works as it should but the first one isnt and i tried to change the code but nothing is working properly.
In Lecturer you are declaring another name variable. This variable is separate from the name variable declared in Person. The call to the superclass constructor is setting the name variable in Person, not in Lecturer. But you don't need the second variable; remove it. You can access the name in Person via the getName method you've already declared. This means that you also don't need to re-declare getName and setName in Lecturer, so the Lecturer class can inherit them.
Also, in Lecturer, the two variables you've declared shouldn't be static. Per the above reasoning, name shouldn't even be there, but even if it should be there, it shouldn't be static. The variable stipend should be there, but it shouldn't be static. When you declare a member variable static, then there is only one variable for the entire class, no matter how many instances you create, which doesn't sound like what you want.
Your constructors should initialize stipend.
You have a static variable inside Lecturer which has the same name as the inherited one from Person and your getter is referring to that static one - are you sure you want these static variables? For completeness if you really want to keep the static one and the inherited one with the same name then change your getter to read return this.name; which will return the inherited name instance variable.... But that method can be inherited from Person class...
There are two name fields in your program , one is private static String name; in Lecturer.java and another is private String name; in person.java .
The thing is that you are just calling Lecturer javs's name field but not setting it.
Fixed the project based on rgettman answer.
Lecturer class should look like this:
public class Lecturer extends Person {
double stipend = 9144;
public Lecturer(String n) {
super(n);
}
public Lecturer(String n, double stipend) {
super(n);
this.stipend = stipend;
}
public double getStipend() {
return stipend;
}
public void setStipend(double stipend) {
this.stipend = stipend;
}
public void writeOutput() {
System.out.println("Name: " + this.getName());
System.out.println("Stipend: " + getStipend());
}
}
I have a class that has a variable of type Name.
public class Holder {
private Name name;
private int snumber;
The Name class has two strings called first and last that are assigned values by setter methods. I would like to send over the strings from the Name class to name in the Holder class, but I'm having trouble doing so. I think I've taken a step in the right direction by doing this
public class Holder {
private Name name;
private int snumber;
public void setName(){
name = new Name();
name.getFirst();
name.getLast();
}
but I can't say that I really know what the correct approach is. I also tried name.setFirst(getFirst) but that doesn't work. Any ideas would be appreciated.
The same way you would if the class wasn't nested.
Your setName() method should take a parameter (maybe 2, first and last) and then invoke the name.setFirstName(), name.setLastName() methods.
Right now, your setName() method isn't doing anything.
E.G:
public class Holder
{
private Name name;
private int snumber;
public Holder()
{
this.name = new Name();
}
public void setName(String firstName, String lastName)
{
this.name.setFirst(firstName);
this.name.setLAst(lastName);
}
}
Here is a good article explaining the relationship between Java inner and outer classes:
https://www.tutorialspoint.com/java/java_innerclasses.htm
class Outer_Demo {
// private variable of the outer class
private int num = 175;
// inner class
public class Inner_Demo {
public int getNum() {
System.out.println("This is the getnum method of the inner class");
return num;
}
}
}
public class My_class2 {
public static void main(String args[]) {
// Instantiating the outer class
Outer_Demo outer = new Outer_Demo();
// Instantiating the inner class
Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();
System.out.println(inner.getNum());
}
}
Note that the example creates instances of both "Outer_Demo" AND "Inner_Demo (outer.new Inner_Demo();).
Ok, so I figured something out that works.
public class Holder {
private int snumber;
private Name name;
public void setName(Name n){
name=n;
}
public Name getName(){
return name;
}
So, can I use same name for public variable in a class and method argument in java?
for example("number" is declared twice):
public class Class1 {
public int number;
public static String function1(String id,int number)
{
//do something
}
}
Yes, you can because the two variables are in different scopes. The method argument is hiding the class attribute for the scope of the function. If you want to access the class attribute within your method anyway, simply use this.number instead.
Yes you can.
The int number declared in the method is only accesible inside de method.
The int number declared as property in the class is accesible in any method for the class.
If you want to access to the number property inside the method, you must use this.
Example:
public static String function1(String id,int number)
{
this.number = number;
}
Yes, if anyhow you have scope related problem then you can qualify the member using the reference this
public static String function1(String id, int number)
{
this.number = number;
//here you assign the class member with the value of the parameter
}
Yes you can use same name for public variable and method argument in java but be careful in case of constructor
You cannot do like this
public class Car{
String carname;
int carspeed;
public Car(String carname , int carspeed){
carname = carname;
carspeed = carspeed;
}
}
instead do this
public class Car{
String carname;
int carspeed;
public Car(String carName , int carSpeed){
carname = carName;
carspeed = carSpeed;
}
}
or do this
public class Car{
String carname;
int carspeed;
public Car(String carname , int carspeed){
this.carname = carname;
this.carspeed = carspeed;
}
}
even you can mix it
public class Car{
String carname;
int carspeed;
public Car(String carname , int carSpeed){
this.carname = carname;
carspeed = carSpeed;
}
}
when you use same variable name for parameter inside constructor and your class property name then they throw error at compile time
I've got a question about my code. I have class Employee declared as abstract. Under it are 3 abstract methods, abstract String department, abstract int work_days and abstract void print_info.
Now, I created second class Tester that extends the Employee abstract class. I implemented the abstract methods.
abstract class Employee {
abstract String department();
abstract int work_days();
abstract void print_info();
}
class Tester extends Employee{
String dept;
int work_days;
#Override
String department() {
dept = "QA Department";
return dept;
}
#Override
int work_days() {
work_days = 5;
return work_days;
}
#Override
void print_info() {
System.out.println("Department :> " + dept + "Working Days :> " + work_days);
}
}
class Demo {
public static void main(String[] args){
Employee emp_tester = new Tester();
emp_tester.print_info();
}
}
Now, when I create instance for Tester and called print_info from Tester class, the variables dept and work_days returns null and 0.
Did I disobey rules in Abstraction? Any critics are much accepted. Thanks
You have implemented it correct and the values you seeing also correct.
When you have not assigned any values and print them, you get their default values.
For Objects, default is null and for primitives their default. You need to set them before you use them.
class Tester extends Employee{
String dept;
int work_days;
public Tester(String dept, int work_days){
this.dept = dept;
this.work_days = work_days
}
And then while creating a Tester,
Employee emp_tester = new Tester("Testing", 24);
call your department function before printing.
public static void main(final String[] args) {
final Employee emp_tester = new Tester();
emp_tester.department();
emp_tester.work_days();
emp_tester.print_info();
}
Unless you call department() and work_days(), the member variables are not initialized now.
Why don't you add a constructor to initialize members?
Tester() {
dept = "QA Department";
work_days = 5;
}
You are not setting the values of dept or workdays.
You probably want to put lines like dept = "QA Department"; in the constructor of the Tester class, if that is what their values are to be.
You should call the getter insteat of accessing the properties:
class Tester extends Employee{
String dept;
int work_days;
#Override
String department() {
dept = "QA Department";
return dept;
}
#Override
int work_days() {
work_days = 5;
return work_days;
}
#Override
void print_info() {
System.out.println("Department :> " + department() + "Working Days :> " + work_days());
}
Hint: Do not call the methods eqauls to the property names. If a value is returned, call the method get...
class Tester extends Employee{
String dept;
int work_days;
#Override
String getDepartment() {
dept = "QA Department";
return dept;
}
#Override
int getWorkdays() {
work_days = 5;
return work_days;
}
#Override
void print_info() {
System.out.println("Department :> " + getDepartment() + "Working Days :> " + getWorkDays());
}
In Java, default value for type String is null and for type int is 0.
That's why you get dept=null and workdays=0.
As i think you have never initialized the values for the variables it will be null. You have to init the variables by calling department() and work_days() first, before accessing them.
Maybe you need to build a getter construct. This can ensure you that work-days/department will always been set when accessing the getter
Something looking like
int getWorkDays(){
if(work_days == 0){
//work_days(); use this instead of my example to call the overriden abstract method
work_days = 5;
}
return work_days;
}
You can also write a getter for the Dept:
String getDept(){
if(dept == null || dept.equals("")){
//department(); use this instead of my example to call the overriden abstract method
dept= "QA Department";
}
return dept;
}
This getters should be used everywhere now like:
#Override
void print_info() {
System.out.println("Department :> " + getDept() + "Working Days :> " + getWorkDays());
}
You can also call the methods to initialize the values in your Constructor like:
Tester(){
work_days();
department();
}
Once you will call method ,
String department()
int work_days()
with the same object , then only your property will get initilize. else, you need to initialize either using Constructor / SIB / IIB. Then after , you can call print_info() method to get the value displayed.