Can someone explain to me in detail the use of 'this'? - java

I don't really understand the use of 'this' in Java. If someone could help me clarify I would really appreciate it.
On this website it says: http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
"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."
and it gives the following example:
For example, the Point class was written like this
public class Point {
public int x = 0;
public int y = 0;
//constructor
public Point(int a, int b) {
x = a;
y = b;
}
}
but it could have been written like this:
public class Point {
public int x = 0;
public int y = 0;
//constructor
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
Yet, I still don't fully understand why x = a could have been written as this.x = x? Why isn't it this.x = a? Why is the x on the left side?
I'm sorry but I am very new to Java. I apologize for boring the experts.

If some variable/argument with same name as object's property is defined, it "overlaps" the name of that property and one should use this.var_name.
So yes, it could be written as this.x = a, but is somewhat redundant.

In the second example one of the arguments is named x. By referencing this.x, you mean the x field/property of the class the method is part of. It could read as:
Point.x = argument x
this is being used to differentiate the two, making the meaning of the code clear.

It isn't this.x = a because there isn't an 'a' in the second example. The point is that you can reuse the same variable name, which is less confusing :-|

The idea is to make it very clear that you are providing values for x and yin your constructor.
Problem is now that due to the scoping rules that within the constructor x refers to the passed value and not the field x. Hence x = x results in the parameter being assigned its own value and the shadowed field untouched. This is usually not what is wanted.
Hence, a mechanism is needed to say "I need another x than the one immediately visible here". Here this refers to the current object - so this.x refers to a field in the current object, and super refers to the object this object extends so you can get to a field "up higher".

this is a reference to the current object, so you access it like any other object - this.x is the x property of this. So x is the argument passed in, which you assign to this.x.
This is namespacing - the idea that a name for a variable only applies within a given block of code. In java, where you are working within a function belonging to the class, you are inside the namespace for that class, however, if you have another variable with the same name as an argument, it will take precedence, and you instead access the attribute via this.
this can also be used in other ways. For example, say I want to draw the current object to the screen in a fictional library, from within the class, I could do:
window.draw(this)
You can also call functions
this allows us to reference the object we are currently 'inside', so we can pass the current object as an argument. This is very useful. (No pun intended).

"this" is a reference to the current object you are using. You use it when you have a name clash between a field and a parameter. Parameter takes precedence over fields.
No clash, no need for this:
public Point(int a, int b) {
x = a;
y = b;
}
But this will work, too:
public Point(int a, int b) {
this.x = a;
this.y = b;
}
Name clash, need to use "this":
public Point(int x, int y) {
this.x = x;
this.y = y;
}
If you did only
public Point(int x, int y) {
x = x;
y = y;
}
then you would just assign parameters with its own value, which effectively does nothing.
There are more usages of keyword "this".

"This" is a hidden "argument" that gets passed for you so that the methods that operate on the object know which object exactly they are to operate on.
Now imagine you pass the argument of name "x" but the class does have that var name defined already. What happens ? Well, the name x that "belongs" to the object and the argument x are not the same data-object yet they share the name.
In order to disambiguate, you need to say explicitly "this.x", which tells the compiler that you're talking about the x that already belongs to "this" object. (That is, the current object you're trying to operate on.)

In the second example, the arguments to the constructor are not a and b; they were changed to x and y, and this.x = x; means "assign this Point class instance's member variable x the value passed to the constructor as x".

This really has to do with how the java compiler identifies variables by their name. Function (formaal) parameters names precede class member variables. In the first example the formal parameter names are a and b and they do not collide with the member variables x and y so writing
x = a;
is logical as x can only mean the member variable class Point.
In the second example x refers both to the formal parameter name and to the member variable. Writing x within the function body refers to the parameter so if you need some other way in order to refer to the member variable x. This is done by explicitly accessing a member via the 'this' keyword.

Related

In Java are object attributes passed by reference to other classes

If I have a class like such:
public class First {
int x = 1;
}
and a second class:
class Main {
public static void main(string args[]) {
First someObject = new First();
someObject.x = 2;
}
}
is only someObject.x equal to 2 or would any object of class First being created afterwards be initialized with it's x attribute being equal to 2. If not, how would one change the default value of x for any object being made of class First?
First of all, you need to read about what "pass by reference" really means. (For example, here.) Passing semantics refer to what happens to arguments in a procedure/method/subroutine/function call. In your example, there is no "passing" going on at all when you are assigning to the x field.
So your
In Java are object attributes passed by reference to other classes
is a meaningless and/or irrelevant question. (But the plain answer is that Java does not support "pass by reference". Period.)
As for what I think you are trying to ask, lets start with some facts:
The Field class declares x as an instance field.
Each instance of First has its own "copy" of the x field.
The x field is part of one and only one instance. It is not shared with any other First instance.
This is irrespective of the declared type of x ... modulo that a field whose declared type is a reference type will contain a reference to an object rather than the object itself. (But int is not a reference type.)
The new First() expression creates a new instance of the First class that is distinct from all other (past, present or future) instances of First and returns its reference.
So, in this code:
First f1 = new First();
First f2 = new First();
f1.x = 2;
System.out.println(f2.x); // prints 1.
We have two instances of First that f1 and f2 refer to (point at) distinct First instances. If you change the x field of one instance does not change the x field of the other intance. They are different fields.
However, if you had declared x as static in First, then x is no longer a distinct field for each First instance. It is now a shared by all instances of First.
As an addendum, how would one change the default value of x in the First class such that any new instance made afterwards would have a difference value of x to start?
Firstly int x = 1; in First is not defining a "default" value in the sense that Java uses that term. It is actually an initialization. (A default value is what you see if you DON'T have an initialization.)
If you wanted to implement application specific default value that is common to all instances of First and that can be changed retrospectively, you need to implement it in Java code. Maybe something like this:
public class First {
static int defaultX = 1;
private int x;
private boolean xSet = false;
public int getX() {
return xSet ? x : defaultX;
}
public void setX(int x) {
this.x = x;
this.xSet = true;
}
}
Note that in order to implement the defaulting behavior we want, we have to hide the x field (make it private) and implement the desired behavior in the getter and setter methods.

How to re-write methods to add together an instance variable and a local variable which produces a new variable of data type Double?

For my assignment I have been asked to create an two methods. These two methods are called "addx()" and "testParsing()". The purpose of these two methods are as follows
addx() method
Calculate 12 + 5 using an instance variable names "x" and a local variable named "x". (the assignment is about scope)
The method which does the addition should add the instance variable x by the parameter x.
Returns a new Double().
testParsing() method
tests that x("12 + 5") returns a Double with the value 17
I have at the moment done the addx() and the testParsing() methods differently to this although the outcome is the same. The way I have done it so far looks far looks like this:
public Double addx(double x)
{
System.out.println("== Adding ==");
this.x = x;
return new Double(x + 5);
}
public void testParsing()
{
if (addx(12.00) == 17.0) {
System.out.println("Adding Success");
} else {
System.out.println("Adding Fail");
}
}
So as you can see, I have not added together an instance variable and a local variable. I have defined the instance variable as the local variable ad added 5 onto it which is not what was asked. I am looking for a way to re-write this so that the addx method adds() method adds both the instance variable which should be equal to 12 and the local variable which should be equal to 5 together to equal 17 and return a new value of type Double (I'm not sure why it is type object Double and not a primitive double but that's what has been instructed.
Here is my attempt of re-writing the methods correctly:
public Double addx(double x) {
System.out.println("== Adding ==");
this.x = 12.00;
x = 5.00;
return new Double();//how do I make the value be stored in this Double()?
}
public void testParsing()
{
if (addx("12 + 5") == "17.0")//error string cannot be converted to double?
{
System.out.println("Adding Success");}
else {
System.out.println("Adding Fail");
}
}
I know that the attempt doesn't make sense, but I'm stuck on how to fix it.
So to clarify:
I want to make addx() add the instance variable x to the parameter x.
testParsing() should test if ("12 + 5") adds up to 17.
Thanks.
addx()
public Double addx(double x)
{
System.out.println("== Multiplying ==");
this.x = x;
return new Double(x + 5);
}
Few things here:
Your sysout statement indicates that you think that you are multiplying numbers. You are not - you are adding two numbers and returning the results.
this.x = x; - I'm not sure what you are trying to accomplish. You are essentially overwriting the value of the instance variable 'x' with the value of the local variable 'x'.
Why are you returning a double where you are adding 5 to x?
Without giving you the answer, here are a few things to explain. Within the method addx(), x refers to the local variable. Therefore, if you call the method with addx(10);, x is equal to 10. To refer to the instance variable, you must use this.x. So, if your instance variable is equal to 1, and you call addx(10);, you expect that the return value will be 11.0. How can you achieve that result, knowing that within the body of the method, x is 10, and this.x is 1?
testParsing()
The intent of this method is to create a unit test for the addx() method. It wants you to test that code. Therefore, one of your variables must be 12, and the other must be 5. You can do the following:
Assign 5 to your instance variable x;
Call addx() with the parameter 12;
Assign the return value of addx() to a Double;
Verify that the double is equal to 17.0.
The verification could be done using assertions, or throwing an AssertionError, for example. Has the instructor provided more details as to how to make that verification?

Confused about Arguments Passing

I'm a bit confused about information passing to methods in Java. I'm currently studying Java basics on Oracle website and while most things I understand with no problem, some things aren't clear enough to me.
https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html
Here is where I'm having doubt. When they write the following code...
public void moveCircle(Circle circle, int deltaX, int deltaY) {
// code to move origin of circle to x+deltaX, y+deltaY
circle.setX(circle.getX() + deltaX);
circle.setY(circle.getY() + deltaY);
// code to assign a new reference to circle
circle = new Circle(0, 0);
}
What do they mean by circle = new Circle(0, 0);? Is it creating a new Cicle object or what? I think what confuses me is how the object parameter is used inside the method declaration.
Can someone explain to me clearly what Passing reference data types is about?
Start with a simpler example:
public class Main {
public static void main(String... args) {
int x = 7;
add(x);
System.out.println(x);
}
public static void add(int y){
y = 10;
}
}
What do you expect this code to print out?
It prints out 7 because even though we're reassigning the parameter received by the add() function, that doesn't affect the original value passed into the function. The x variable in the main() method is still 7.
The example code is just showing you a more complicated example of that with Objects instead of primitives. The lesson you're supposed to learn is that reassigning parameters in a function does not affect their original values.
These changes will persist when the method returns. Then circle is assigned a reference to a new Circle object with x = y = 0. This reassignment has no permanence, however, because the reference was passed in by value and cannot change.
Read the last paragraph carefully.
You are able to modify the attributes of the referenced circle, but if you assign the variable a new reference, no changes were made to the original object. It only tells myCircleto refer to a newly created object. And this object gets immediately garbage collected after the method goes out of scope.
Explanation for the two questions you asked:-
circle = new Circle(0, 0) means that we are assigning values to the constructor of Circle object .
Yes this is creating new circle object by passing values to the reference variable circle.
Hope it helps!

Setting variables in Constructor using this

So I am OK with java, but new to C++. I am basically trying to make a Constructor for C++ with a parameter passed, and assign that value to the field for that object using this. So here is what it would look like in java:
//Foo fields
private int num;
//Foo Constructor
public Foo(int num){
this.num = num;
}
How can I use this to set a variable like that in C++? Or is this not an option? Thanks!!
C++ has an even cleaner approach, called constructor initializers. Instead of having lots of assignments, you can use this syntax:
public MyClass::MyClass(int num): someVar(num), someOtherVar(0) {
// constructor here
}
If you really, really want to use this, remember that in C++ this is a pointer, so you have to use the pointer dereference operators, so either
this->num = num;
or
(*this).num = num;
Use this->num, as in c++ this is a pointer, to access struct/class members via pointer you have to use -> instead of . between variable and member name, here is from manual
expression can be read as
*x pointed by x
&x address of x
x.y member y of object x
x->y member y of object pointed by x

Are all immutable objects re-usable?

From the effective Java book it states that "An object can always be reused if it is immutable".
String s = "shane";
String p = "shane";
This version uses a single String instance, rather than creating a new one
each time it is executed. Furthermore, it is guaranteed that the object will be
reused by any other code running in the same virtual machine that happens to contain
the same string literal.
What about the below final class which is also immutable?. Can the Point Object be re-used?.
public final class Point {
private final int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y;
}
Can anyone provide me an example of the above immutable class where its object/instance can be re-used?. I am just confused on how the re-usability would occur?.
I am able to relate with String and Integer Classes, but not with user defined classes.
It "can" be reused, in that you could use the same object in multiple places and it would be fine. But it won't be, automatically. The JVM itself manges reuse Integer objects for the range -128 - 127
Integers caching in Java
"intern"ed strings (including literals) similarly are managed by the JVM. The closest to automatic reuse you could have here would be to make the constructor private, and create a factory method:
Point.create(int x, int y)
And have the implementation maintain a cache of objects that you'd like to reuse (like Integers effectively cache -128 to 127) But you'll have to do the work yourself.
Edit:
You'd basically have:
private static final Map<Pair<Integer, Integer>, Point> cache = new HashMap<>();
public Point create(int x, int y) {
Pair<Integer, Integer> key = Pair.of(x, y);
if (cache.containsKey(key)) {
return cache.get(key);
}
Point p = new Point(x, y);
cache.put(key, p);
return p;
}
Edit:
Alternatively, add hashCode() and equals() to the Point class, and just use a HashSet. Would be simpler.
Re usable simply means to change the "reference" variable value.
e.g. an int is can be reused and its value changed
a data type is a little different the reference variable is re-initiated for example using the "new" instane e.g. myframe=new JFrame()
variables declared "final" are a "constant" and are mutable.
The class above itself requires its reference variable at initiation to be declared "final" to be mutable although its contents is effectively mutable, the difficulty is the definition of context of which (variable or class definition) part is the mutable.
Immutability means when an object is created its state at the creation time is going to stay through out its life. And yes, the class you showed and object of that class is immutable, as you are initialing states in constructor and there are no setters.
About the re-use: yes you can reuse the same object over and over where an object of type Point is required, but for that purpose you have to hold on to an object once it's created for that. As #James
suggested, you can use a factory for object creation and that factory can decide if it needs to create a new object or use an existing one when you ask for a Point object.

Categories

Resources