I figured out how to have an object pass itself to another and have a field in it updated.
I did so by having ObjectA pass itself to ObjectB. Then ObjectB changes a field in ObjectA.
Starting in Main Method: (and leaving out method headers and such)
ObjA.changeField(Obj2)
In ObjectA
Obj2.callChangeMethod(this);
In ObjectB
Obj1.makeChange();
What I'm confused about is why did I have to pass "this" in line2 versus passing ObjA?
Thanks
The reason is quite simple actually: it all has to do with the scope of the variables.
Here is a slightly embellished version of the code you presented:
public static void main(String[] args) {
ObjectA Obj1 = new ObjectA();
ObjectB Obj2 = new ObjectB();
Obj1.changeField(Obj2);
}
The thing to notice about this code is that Obj1 and Obj2 are declared inside of the main method. This means that they belong to the main method, and cannot be used outside of main. This is what the "scope" means. If a variable is declared inside a class, only that class has access to it. If declared in a method, only that method can use it. The same holds for loop structures, and any other kind of block you can imagine. Essentially, if the variable was declared inside a pair of {}, then it belongs to that pair of {}.
So now if you look at your ObjectA class, you'll notice that it sits all by itself - it wasn't declared as part of the main method, so it can't use the variable Obj1 - the ObjectA code has no idea that Obj1 even exists.
That is why you must use the this keyword. You don't have access to Obj1, so you need to use a "variable" that you do have access to - in this case, you have this which always refers to the current instance of the class.
So although you are still using the same object (the one created by new ObjectA()), you simply have different variables which refer to that object, depending on which code you are currently looking at. The scoping rules do get a little more complex, but the more you play around with Java, and the more you understand classes vs instances vs references to instances, the easier it becomes to use them comfortably.
The only reference an object has to itself is the this keyword. Ultimately, there is no other way for an object to refer to itself.
Related
I'm having confusion in calling a non-static method
class A {
void doThis() {}
public static void main(String... arg) {
A a1 = new A();
a1.doThis(); // method - 1
new A().doThis(); // method - 2
}
}
I know that both method-1 and method-2 will call doThis(), but is there any functional difference?
There won't be any difference in execution of those methods but in case of new A().doThis() your're going to lose the reference to the instance of an object you've invoked the method on and you won't be able to use it further in your code. All the changes this method could've done to internal state of the instance will be lost.
In case of A a1 = new A(); a1.doThis(); you're going to preserve the instance of an object (in variable a1) and potential changes made to its state made by method doThis(). Then you'll be able to continue working with this object.
Is there any functional difference?
Both will behave in the same way.
The second option doesn't allow you to reuse that instance again. It may be convenient and concise in one-line return statements (for instance, consider the builder pattern where each constructing method returns a half-initialised instance):
return new Builder().a().b().build();
or if an object was created only to perform a defined action once.
What will be the reference of a new object in method-2?
It is no longer exist (more precisely, we don't have access to it) unless the doThis returns this which you could be able to put in a variable after method execution.
Can I say that method-2 is an improper way of calling a non-static method?
No. Why should we create a variable if this variable will never be used afterwards?
Let's see what the code says in plain English:
A a1 = new A();
a1.doThis();
Create a new instance of A.
Store a reference to it in the variable a1.
Call doThis() on our instance.
Whereas new A().doThis(); reads as:
Create a new instance of A.
Call doThis() on our instance.
So the only difference is whether you store it in a local variable or not. If you don't use the value in the variable any more, then that difference doesn't matter. But if you want to call another method on the same object, let's say a1.doThat(), then you're in trouble with the second solution, as you haven't got a reference to the original instance any more.
Why would you want to use the same object? Because methods can change the internal state of the object, that's pretty much what being an object is about.
Lets take a look at both these methods one by one.
Method-1
A a1 = new A();
a1.doThis();
In method-1, you have a reference of newly created instance of A, i.e a1 and you can call as many methods on this instance of A using this reference a1. Basically you can reuse that particular instance of A by using its reference a1.
Method-2
new A().doThis();
However in method-2, you don't have any variable that stores the reference of your newly created instance of A. How will you refer to that particular instance of A if you have to call any other method on that particular instance of A ? You will not be able to re-use that instance of A if you create an instance using method-2 and you will lose that instance as soon as it is used.
case1:
A a1 = new A();
a1.doThis();
The above two line means object created and doThis(); executed but still object available in the heap memory.
case2:
new A().doThis();
A class object created and doThis(); executed after immediately GC(GarbageColletor) will activate to remove the A object from the heap memory bcz it's a non-referenced object and we can call this object as an anonymous object.
I have a object I initialize in a method like :
public void something()
{
Dummy obj = Factory.getDummy();
method2(obj);
}
now, this Dummy object is to be used by many methods
public void method2(Dummy obj)
{
method2(obj);
....
}
Now, my doubt is how this scenario must be handled, the way I am doing it. Or, make obj in something a class level field and initialize in something.
like:
private Dummy obj;
public void something()
{
obj = Factory.getDummy();
method2(obj);
}
And use in subsequent methods. (Removing parameters from the methods).
So, what is the best way of handling this situation? and Why?
If it's strongly associated with the class, make it static.
If it's strongly associated with an instance, make it a non--static member.
If it's strongly associated with a method invocation, or the current thread, or you can't decide about (1) or (2), make it method-local.
Generally you should minimize the scope of one variable. But, if the variable is very used within your class, you should declare it as class-level, as instance variable.
You should declare obj as a class-level field and then instantiate it in the constructor.
But more points to clear:
if something() and the methods like method2() that expect the Dummy object, are located inside the same class, then you even don't need to pass the object. In that case, the above statement is upheld
if not located in the same class, then pass the object by invoking the methods through their instances or classes based on what type they're.
If some property is associated to class, then that property should be static. That is, if some property is same among all the instances of classes, then that property should be the static in class.
If some property is differing for every instance of class, then that property should be member variable ( non-static variable ) of the class.
If some property needs on temporary basis for some operation then make that property as local variable of the operation ( method ).
I am new to Java and I'd like to figure out why some code is written in one way instead of another. When you construct an object in Java, the syntax is something like
class variable = new class(parameters);
or
class variable;
variable = new class(parameters);
I wonder why the class name has to be invoked twice. As documented on Wikipedia, Python (which I don't know either) follows what according to me is a more intuitive approach, i.e.
variable = class(parameters)
Is it because Java can handle other possibilities?, e.g.
class1 variable = ... class2(parameters)
Thanks in advance.
Because the left hand side can be a reference type and the right hand side it can be any assignable object type.
This assigns the reference variable variable of type class1 an object of class1.
class1 variable = new class1(parameters);
This assigns the reference variable variable of type class1 an object of subclass1, where subclass1 can be a subclass of class1 or an implementation of class1 interface.
class1 variable = new subclass1(parameters);
Python uses Dynamic Typing (Duck Typing) and hence you need not declare a variable.Dynamic typed languages are those in which variable type checking is done at run-time.
Static typed programming languages are those in which variables need not be defined before they’re used. This implies that static typing has to do with the explicit declaration (or initialization) of variables before they’re employed. Java is an example of a static typed language. Statically typed languages that lack type inference (such as C and Java) require that programmers declare the types they intend a method or function to use. This can serve as additional documentation for the program, which the compiler will not permit the programmer to ignore or permit to drift out of synchronization.Static typed languages are those in which variable type checking is done at compile-time.
Python (which I don't know either) follows what according to me is a more intuitive approach
The concern with dynamic typing, like this is :
variable = class(parameters);
In future if by mistake you misspelled the variable name variable with varaible , it would not be caught at compile time , but you can get erroneous output or exception at runtime. With static typing , Java detects such flaws at compile time itself.
Because they mean different things - and don't need to be the same.
The class descriptor on the left defines the type of the variable. This constrains what can be assigned to that variable, and also provides some guarantees to callers about what the objects there can do.
The class name when it appears on the right is actually the "method name" of a constructor. You're calling a method which creates a new object. The object you create can be anything, so long as it's assignable to the type of the variable.
So for example, you can do this:
Object foo = new String("bar");
or this:
Collection x = new ArrayList();
(though in practice you'd probably want to use generic parameters on that last one - I've left them out here so as not to confuse the question of classes.)
Java is a static typed programming language. However, Python is a dynamic typed programming language.
Wikipedia has very good explanation here.
Class name has to be invoked twice because you have to specify the type of the instance.
You can also do things like this when creating new instance:
public class Test extends Test1 {}
...
Test1 test = new Test(parameters);
Doing things like this will determine which class' variables and methods you can actually access while maintaining stuffs such as class fields.
SomeClass variable;
variable = new SomeClass(params);
The first line declares a variable and states that it is of type SomeClass. At this point the variable is empty and doesn't reference anything.
The second line creates a new object of type SomeClass and stores a reference to it in variable.
Writing both things in one line like this:
SomeClass variable = new SomeClass(params);
can be done to make things shorter. But at the end there is always a variable declaration and an object construction. Variables must always be of some type, you can't declare a variable without type (Java is strongly typed).
The left hand side (reference definition type) is a reference to an object or instance that can be the type of that class or any subclass of that reference type. Also, in accord with the following reference Python is a dynamic type programming language where every variable name (unless it's null) is bound to only an object. Java, on the other hand, is a statically-typed programming language.
I have noticed in the code in my system that someone instantiated an anonymous class as follows
Class ExampleClass{
MyObj obj;
methodA(new ClassA(){
#override public void innerMethodA(){
//code...
}
});
}
So far so good.
Now, in order to use obj that was declared before the method I usually define it as final.
I don't really understand why but i do because the compiler asks.
In this code i see in innerMethodA() the usage of
ExampleClass.this.obj()
without final.
My questions :
1. why do I have to put final when I use obj?
2. what is ExampleClass.this ? Notice that ExampleClass is the Class not an instance. then what is the "this"? if it has several instances?
3. What happens if I change the obj while the inner method runs (in my code inner method runs in a loop so I plan on changing it . will it explode?)
You have to use final when you capture the variable of a local variable... not an instance variable of the enclosing class.
ExampleClass.this is a reference to the instance of ExampleClass associated with the instance of the subclass of ClassA. In your case, it will be the same as this within methodA.
It won't explode - it will just change the value of obj. Think of it as capturing the value of ExampleClass.this (so you can't change that) but you can change the data within the object referred to by ExampleClass.this.
There are no "true" closures (functions that capture scope) in Java. See e.g.http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-different
You can use this form to reference ambiguous methods / variables in the scope of "ExampleClass".
You cannot change the reference. What you can do is use an indirection, e.g. a final reference to an object that can swap it's values. An example would be the class of Atomic value holders, e.g. AtomicReference.
Because, the way you described it, in this case, they are not using ExampleClass.this.obj, they are calling the method ExampleClass.this.obj().
ExampleClass.this refers to the encapsulating instance of ExampleClass in which this ClassA instance is instantiated.
Not necessarily.
Why does this code return "class java.lang.Object" ?
Object a = new Object() {
public Object b = new Object(){
public int c;
};
};
System.out.println(a.getClass().getField("b").getType());
Why does the inner-inner type get lost? How can I reflect the c field ?
Edit:
This one works (as pointed out in some answers):
a.getClass().getField("b").get(a) ...
But then I have to invoke a getter, is there any way to reflect c with only reflection meta data?
Because b is declared as Object:
public Object b = ...;
There is a distinction between type of variable (static type) and type of the object referenced by that variable (runtime type).
Field.getType() returns static type of the field.
If you want to get runtime type of the object referenced by the field, you need to access that object and call getClass() on it (since a is declared as Object and therefore b is not visible as its member you have to use reflection to access it):
System.out.println(
a.getClass().getField("b").get(a).getClass());
UPDATE: You can't reflect c without accessing the instance of object containing it. That's why these types are called anonymous - a type containing c has no name, so that you can't declare field b as a field of that type.
Let's look at this line carefully:
System.out.println(a.getClass().getField("b").getType());
First, your take the a variable. It is of some anonymous subclass of the Object. Let's call that class MyClass$1. Okay, so far so good.
Next, you call the getClass() method. It returns the class of a, that is, a description of the MyClass$1 class. This description is not tied to any particular instance of that class, though. The class is the same for all instances, be it a or whatever else (unless different class loaders are used). In this particular case, however, there can be only one instance, because the class is anonymous, but the mechanism is still the same.
Now, from the class, you get the field b. As the class isn't directly tied to any of this instances, the field has nothing to do with a either. It's just a description of what exactly the field a of the class MyClass$1 is.
Now you get its type. But since it isn't tied to any instance, it can't know the runtime type. In fact, if the class wasn't anonymous, you could have numerous instances of MyClass$1, each having different value in a. Or you could have no instances at all. So the only thing getType() can possibly tell you is the declared type of b, which exactly what it does. The b field could in fact be null at that point, and you'd still get Object as the result.
The Field class provides the get() method to actually access that particular field of some object, like this:
System.out.println(a.getClass().getField("b").get(a).getClass());
Now you get something like MyClass$1$1, which is the name of the anonymous class of the object that field b references to, in the a instance.
Why does the inner-inner type get lost?
Because you are getting the type type of the field "b" (Object), not the type of the anonymous inner class of which you assigned the instance to "b".
How can I reflect the c field ?
You could use this
System.out.println(a.getClass().getField("b").get(a).getClass().getField("c"));
instead. This gets the value of the field "b" and it's class, but this only works if "b" is guaranteed be not null.
Doing this seems to indicate a bad design, there might be other ways to archive what you want to do with this. But without knowing the purpose, this is everything I can answer.