I have come across such a code and my Java knowledge is not enough for it - I am pretty sure it is
something simple, but I have not found an explanation as don't know how to express it in google.
Here is the abstracted code, I hope nothing is missing:
public class A{
Car car;
.
.
.
public A do() {
car.move(somewhere);
return this;
}
}
public class B{
protected A doSomething(final A a ){
a.do();
return a;
}
}
My first question is what does "return this;" mean here? http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html does not include such a case.
Second is how a.do() works in method doSomething()? Method do() is supposed to return a value, yet it is not assigned anywhere?
Lastly, I suppose that "a" returned from doSomething() was changed in this method. Is this allowed, as "a" is final?
return this
Returns the object itself. In case of a.do() a is returned. What is this good for you might ask? It enables this:
a.do().do().do();
return this; - Being that, the return type is an A object, when the .do() method is called, the method will return this, this is the exact same instance that called it.
public A doSomething(final A a), the only contract here is that an A object is returned. What happens in the code block doesn't matter, as long as a null or class that extends A is returned.
final A a declaration, simply means the memory location address by variable a cannot be re-assigned.. i.e. a = null; or a = new A() would throw an exception
return this;
is exactly the same as any other return statement - it returns a reference to this. For example, if I had a variable Car a, the statement a.do() would return a reference to the same car a.
As for final, it doesn't mean immutability - it just means you can't reassign other data to the memory location. You can modify the Car that's already there - but not replace it with another Car.
a is final that means its memory address will not be changed again and a.do is simply calling the method do that will cause the move method of car to be called and return this returns the reference to the same object.
(First do is a keyword. So you renamed for clarity.)
return this; allows:
protected A doSomething(final A a ){
return a.do();
}
Which is exactly the same.
final variable declarations mean that you may assign only once to it (for fields), most often immediately at the declaration. So it is used for (dynamic) constants initialised only once.
do() is a method of class A. It can be called on any instance (object) of class A.
this refers to the current instance.
return this means that the method will return the instance of class A on which it (the method) is applied.
I'm not sure what such a method can be used for, though.
what does "return this;" mean here?
As mentioned over and over this it is always used within a context of an object and it is a reference to that object.
public A do() {
car.move(somewhere);
return this;
}
Return this, in the do() method just returns a reference to the current object.
Second is how a.do() works in method doSomething()? Method do() is supposed to return a value, yet it is not assigned anywhere?
Method do() just does some operation on the instance it is called from. because it is public it can be called from any place, and because it is not static it can be called only from an already created instance. That is why it needs to be called like a.do() and thats what it returns: the a reference.You dont have to assign it to anything, it will still operate within a reference and its operation will eventually update the a related state.
Lastly, I suppose that "a" returned from doSomething() was changed in this method. Is this allowed, as "a" is final?
Perfectly allowed. Java does not support pass by reference method so you can change the object the a reference points to however you cannot change the reference itself withing doSomething() method context.
Using return this; at the end of methods is a technique called Method Chaining and can be a very convenient way of performing a chain of operations on an object.
StringBuilder is a good example:
String s = new StringBuilder().append("Hello").insert(0, "Goodbye").delete(7, 12).append(" :)").toString();
NB: It can also be used to make code seem over-complex so it should only be used where appropriate.
Related
I couldn't find information if it is possible to write public void in constructor section. Is it possible?
At the byte code level, a constructor is always void so it would be redundant to specify it. i.e. the constructor is always called <init>V i.e. the V is the return type where V == void. Similarly the static initialiser is <clinit>V You will see this notation if you take a stack trace (e.g. print an exception) while in these methods.
The constructor actually takes the object to be initialised as an argument as the object is created before calling the constructor. Note: you can create the object without calling a constructor with Unsafe.allocateInstance(Class)
I couldn't find information if it is possible to write public void in constructor section. Is it possible?
It is not possible to write it as Java distinguishes a constructor from a method is that it must have the same name as the class, and it must not specify a return type. If you specify a return type, it assumes it's a method.
The notation x = new Clazz() also limits the number of return values to 1 which is the object. There is no easy way to modify this notation to return more than one object. i.e. supporting a return type for constructors would not be easy.
If you want to define a return type, most likely you are thinking of a factor method like this.
public static MyInterface createObject() {
return new MyClass();
}
Note how the return type is different to the class actually created, but there is still only one reference returned.
The constructor syntax is defined in the Java Language Specification. Anything else is incorrect.
The question is unclear. Peter Lawrey answered one interpretation, this is an answer to another.
You cannot declare methods within a constructor. You can, however, declare a class and declare variables.
Because you are able to declare a class within a constructor, you could declare a method inside of a class and then use the class. If the method isn't static you can construct an object of the class.
No, Java only allows a method to be declared within a class, not within another method or constructor.Indirectly you can do something like this :
public A() {
class B {
public void m() {
}
}
}
What is the difference between using a method with void, and a constructor? For instance:
public class Time {
public void getMethod() {
}
public Time() {
}
}
Where do I use what?
Thank you
Constructor is called after creation of a new Object(). Typically to do some initialization, to prepare the object. Methods - you call them when you like.
Constructor can be called only once on a certain object. Methods can be called many times.
Constructor can't be static, because it would be not logical, static says "belongs to class, not an object". Methods can be static.
Constructors are methods that belong to a class that are associated with its creation. When you declare an object using Object a = new Object(); This is where constructors are invoked.
You should use constructors to organize any data that you'll need for the rest of the class. For example, if you are making a Time class, the Time constructor might get the current time and set it in a variable to use later.
Other methods are simply that. They are the methods that do some calculations or work for the class. For example, you might have a method that accepts a date and returns the days between the date entered, and the current date.
'void' is simply the return type of the method.
Constructors do not have return types.
A constructor is used to create a new object. Its use leads to the return of a reference to a new object (although technically the constructor does not return the reference itself). As such void would be a meaningless keyword for a contructor. It is used as Object o=new Object(parametersIfApplicable)
On the other hand a method with a void return parameter returns nothing (but would usually change the internal data within the object (or less frequently change one of the objects passed to it); otherwise calling it would be pointless).
Summary
Calling a contructor leads to a new object and returns a reference to it
A (non static) method is called on an existing object to do some work; it returns nothing
A void method specifically does not return any data or object. Pragmatically, a constructor does not return anything.
From a hardware perspective, it initializes the information given at construction allocated by the object declaration by the caller; Doughty provides a broad overview under "References to and Creating Objects".
In order to use the method, getMethod(), you must create an instance of the class Time which is done by constructing its object defined by its constructor.
Time currentTime; //Declaration of object only allocates space in memory for it
currentTime = new Time() //Constructs an instance of Time
//and assigns the object reference to variable currentTime
Then using the method with return of void:
currentTime.getMethod();
Simply calls the method so it performs its tasks. It returns no data or object, but control back to where it was called.
Most of an object's methods will be called the same way when invoked by an object under construction as when invoked from anywhere else. Constructors are different. A constructor is a special sort of void method which cannot be called directly from "normal" code. Instead, all constructor calls must take one of two forms:
A call made at the very beginning of one constructor to a another constructor in either the present class or superclass.
A call generated by the system as part of the following sequence (pseudocode given for x = new Foo(123);):
// "Magical" system routine to create an object without running constructors
Foo temp = InternalSystemMagic.CreateNewObject([foo's type]);
temp.Foo_constructor(p1); // Now invoke the constructor
x = temp; // Note that if the constructor throws, x will not get set.
Note that the compiler can produce code which will first create an object of type Foo without running the constructors, and then call a constructor on the newly-created type, even though neither operation would be legitimate without the other.
So I have a simple programming question that I can't seem to find the answer for. While browsing some code from Google I noticed that they put 'this' in front of a lot of methods in their code. What is the purpose of doing this? Does it have any benefits over not using it?
An example:
this.doMethod();
Compared to:
doMethod();
I'm sure its a simple answer, I just like being able to understand all of the code that I read.
No, it makes no difference at all for method calls. Use whichever you find more readable.
Note that it does make a difference when disambiguating between instance variables and parameters (or other local variables though). For example:
public void setFoo(int foo) {
this.foo = foo;
}
That's assigning the instance variable a value from the parameter - just using foo = foo; would be a no-op.
this represents the object instance of the current class. In programming practice, most of the time, it is used to break the ambiguity. e.g. in example, there is a class variable named name and method parameter named named, so this is used to differentiate the two.
public void setName(String name){
this.name= name;
}
If you don't have any ambiguity then it doesn't create much difference i.e. setName("John"); and this.setName("John"); is same thing. But still there is one difference. this.setName("John"); follows the same pattern as you are calling the method on objects(e.g. emp.setName("A");); here this representing the sane class object.
There is no difference between them at all. You always call a method on some reference. If you don't use any reference, this reference is implicit.
So, doMethod() is same as this.doMethod(). By using this, you just make it explicit.
One place where it is required to use this reference explicitly is the place where you are assigning the value of method/constructor parameter to the instance variable, and both have same name, as in the below example:
public Demo(int var) { // Constructor
this.var = var;
}
So, in the above example, this.var refers to instance variable and is different from var, which refers to constructor parameter.
Eclipse will give an error, "The left-hand side of an assignment must be a variable", when I try something like:
public class Thing{
String a1;
int a2;
public void meth(){
Thing A = new Thing();
this = A;
}
}
I had to assign each variable (this.a1 = A.a1; this.a2 = A.a2;) as a work around.
Are there other ways to do this without going through each variable field?
And if this is not a variable what is it called?
this is a pseudo-variable that points to the current instance of the object, it can not be reassigned. It's also considered a keyword in the language, according to section §3.9 of the Java Language Specification.
No, there is no easy shortcut.
And if "this" is not a variable what is it called?
this is not a variable, it's a keyword.
Even though this is special, in many respects it acts like a reference. Therefore, for consistency, this = A would have to be a reference assignment, which doesn't quite make sense.
You seem to be expecting this = A to perform a field-by-field copy from A to this, and indeed Java's designers could choose do that in this case. However, this would be inconsistent with other reference assignments, and the overall benefits of having this as an exception are not at all clear.
this refers to this instance of the class.
You cannot assign to this
this is a java reserved keyword which refers to the current object. its not a variable its a java reserved keyword.
so this = A; is invalid. using this keyword we can refer to any instance variable or method of the current object. you have to refer to the instance variable like:
this.a1 = A.a1;
From Doc:
The most common reason for using the this keyword is because a field
is shadowed by a method or constructor parameter.
You can't assign to this in Java. It's not a variable; it's a keyword.
One thing you might consider, if you don't need a particular instance, is just returning your new instance.
public class Thing{
String a1;
int a2;
public Thing meth(){
Thing A = new Thing();
return A;
}
}
and you'd use it like
whatever = whatever.meth();
According to java lang spec §15.8.3 this is a keyword that is either an expression or statement
When used as a primary expression this denotes a value that is a reference to the object for which the instance method was invoked.
Expression: Something which evaluates to a value. Example: x++
The keyword this is also used in a special explicit constructor invocation statement
Statement: Syntactic elements that control the execution of a program, which are executed for their effect and do not have values Example: if (true)
In either case it is not a variable
Variable: A storage location with an associated type
In your case this is an expression and not a variable. But for all intents an purposes just call it a keyword
Keyword: A character sequence, formed from ASCII letters, are reserved for use ... that cannot be used as a variable name
this refers to the owner of the method.
In this case, the owner is the object itself.
Sometime, this may not refer to the class that you are writing code. Such as in the annoymous class. A common example is the anonymous listener.
button.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
this; // refers to the ActionListener
}
}
);
In addition, you can return this can do method chaining. Supposed you have a class called Homework and it has a method addTask.
public Homework addTask(String task){
return this;
}
you can call the addTask method like
homework.addTask("a").addTask("b").addTask("c");
I think the OP is asking for the ability to assign the contents of one object to another, rather than to assign a new value to the "this" pointer. C++ has this ability -- you can override the assignment operator -- but Java has no such ability.
It would be a nice feature to have in some occasional cases, but it's simply not currently possible, and it doesn't really fit the Java "mold" to provide the function in the future.
The capability would be more useful (and there would be more motivation to provide it) if Java allowed objects to be embedded in other objects (vs simply embedding referenced), but that's not in the cards either.
There is no1 way to copy the values of all fields from one instance onto another in the basic Java language. And you should typically not need it. You can most often just replace the reference to the new instance or work directly on the target instance.
In your case when you want to reset all fields of a object to the initial values (and there is seldomly a need for it) you typically use a reset method which eighter works on its own instance or is a static one working on any given object.
So
class A {
String a1; int a2;
void reset() { a1 = ""; a2 = 0; }
}
would be used as
A a = new A();
// modify a
a.reset();
and
class A {
String a1; int a2;
static void reset(A anotherA) { anotherA.a1 = ""; anotherA.a2 = 0; }
}
and use it like:
A.reset(a);
In both cases it makes sense to use the reset method also for setting the initial values in the constructor: A() { A.reset(this); } or A() { this.reset(); }
1 actually there are some libraries to do it, and you can code it with the help of reflection, the only reason I see it is used is to implement a clone() method or for some kind of wrapping/stubbing.
It sounds to me like what you're trying to do is have a method that reinitializes your object, i.e., set's it back to it's initial values. That's why you want to create a new object, and assign it to the current object, right?
If that's the case, let's try a different way of doing it, since, as has been said, you can't reassign this.
What if, instead of doing that, you tried something like this:
public class Thing {
String a1;
int a2;
public Thing() {
this.meth();
}
public void meth() {
this.a1 = "a1";
this.a2 = 2;
}
}
This way, Thing.meth() actually initializes your object, and the constructor calls it when the object is created. Then you can call it again whenever you'd like.
==Disclaimer, I don't know java==
You would want to assign manually.
I'm not sure why you are trying to create a new instance of Thing inside Thing, but as you don't set the values of a1 and a2 you would need to assign them the way you did.
this is a reserved keyword pointing the class object it is inside.
For example, if you wanted to have another function named fish() your code may look something like this.
public class Thing{
String a1;
int a2;
public Thing meth(){
Thing A = new Thing();
return A;
}
public Thing fish(){
this.a1 = "foo";
this.meth();
return A;
}
}
When you do this = stuff; you are trying to replace the current object instance reference (in this case, the one that you are initializing in the constructor) with another thing, and (in the particular case of java) thats illegal and the language forbids you of doing it.
Think about it, if you could replace the reference to your current instance just like that, then you could incur in some serious memory and security problems (the reference to the constructed object will be lost and overrided by some unknown object).
What is totally valid is referencing members of your current object using the . operator, because they are owned by this, so no problems should arise (at least not evident ones).
The JVM has some inner security measures (e.g., method max stack size verification, class file format validation, etc) that prevents from easy binary manipulation and are enforced by the language syntax. This could be seen as one of those.
I have a constructor like as follows:
public Agent(){
this.name = "John";
this.id = 9;
this.setTopWorldAgent(this, "Top_World_Agent", true);
}
I'm getting a null pointer exception here in the method call. It appears to be because I'm using 'this' as an argument in the setTopWorldAgent method. By removing this method call everything appears fine. Why does this happen? Has anyone else experienced this?
You can pass this to methods, but setTopWorldAgent() cannot be abstract. You can't make a virtual call in the constructor.
In the constructor of an object, you can call methods defined in that object or base classes, but you cannot expect to call something that will be provided by a derived class, because parts of the derived class are not constructed yet. I would have expected some kind of compiler error if setTopWorldAgent() was abstract.
In Java, you can get surprising behavior with the contructor and derived classes -- here is an example
http://en.wikipedia.org/wiki/Virtual_functions#Java_3
If you are used to C# or C++, you might think it's safe to call virtual functions and not be calling overridden ones. In Java, the virtual call is made even though the derived class is not fully constructed.
If this isn't what's happening, then presumably, all of the parts of this that setTopWorldAgent() needs are initialized -- if not, it's probably one of the members of this that needs to be initialized.
Edit: thought this was C#
Out of curiousity, why are you passing 'this' to a member function of the same class? setTopWorldAgent() can use 'this' directly. It doesn't look like your constructor or setTopWorldAgent() are static, so I'm not sure why you would pass a member function something it already has access to.
Unless I'm missing something...
Why would setTopWorldAgent need this as an argument? Based on the invocation, it's an instance method, so it could reference this without needing to receive it as a parameter.
"this" should never be null. Are you sure that the exception is being thrown because of that?
Something to beware of is that if the method is virtual, or calls any virtual methods, then a method belonging to a subclass might be run before the subclass's variables are initialised.
I think more to the point, why on earth are you passing 'this' as a parameter to a method in 'this'?
The following would test what you say is happening to you and I have no troubles with it.
public class Test {
public Test() {
this.hi(this);
}
public void hi(Test t) {
System.out.println(t);
}
public static void main(String[] args) throws Exception {
Test t = new Test();
}
}
Given that setTopWorldAgent appears to be an instance method, why are you passing through this to it anyway?
The error must be somewhere else because the above code definitely works, the null reference must be something else.
If your Agent is implementing ITopWorldAgent then you should actually do this:
Agent agent = new Agent("John", 9);
agent.setTopWorldAgent(agent, "Top_World_Agent", true);
If not, then why you are setting something in the manner you are?
I presume that something in the setTopWorldAgent method is using a value that hasn't been initialised yet in your constructor.
this is not null, that much is sure. It's been allocated.
That said, there's no need to pass this into the method, it's automatically available in all instance methods. If the method's static, you may want refactor it into an instance method.
The rules of Java state that you should never pass 'this' to another method from its constructor, for the simple reason that the object has not been fully constructed. The object it references may be in an inconsistent state. I'm surprised that the actual 'this' reference is null, but not at all surprised that some member of 'this' is null when it is passed to setTopWorldAgent, and that the method is throwing the exception because of this.
Usually you can get away with passing 'this' from constructors as long as you don't actually access any members or call methods for example if you want to set a reference to 'this' in another object.
In this case of course the argument is unnecessary as the method already has a reference to 'this'.
Glad you got to an answer. I'd like to add that passing 'this' as a parameter can lead to unexpected concurrency issues. You basically are providing the possibility of the state of the object to be unsafely manipulated by potentially non-thread safe code.