this.method() is referring to? - java

I have a question regarding this. statement.
Let's say I have this code right here (very stupid and useless but gets the message across):
class Calculate{
int x,y;
final int g = 5;
//Constructor
public Calculate(int a, int b) {
x = a; y = b;
}
public int sumAddG() {
return (x+y+g);
}
//comparing method
public boolean same(Calculate in) {
if(this.sumAddG() == in.sumAddG()) { // <-- This is what I am curious about
return true;
} else {
return false;
}
}
So do I have this code right? When I am using this.SumAddG() - Am I referring to the result of the method SumAddG() using the instance variables of this class instance?

this refers to the actual instance whose same() method has been invoked. Eg. take the following code:
Calculate a = new Calculate(0, 3);
Calculate b = new Calculate(0, 4);
boolean calcFlag = a.same(b);
In this case the this in the method same() will refer to a while in will refer to b.
Update for this line:
if(this.sumAddG() == in.sumAddG()) { // <-- This is what I am curious about
you have a boolean method. In if you're evaluating a boolean expression and you return a boolean true value if the expression itself is true. This can be simplified by simply writing
return this.sumAddG() == in.sumAddG();
This will return directly the evaluation of the two instance's equality. Generally, it is considered good practice in case of boolean methods to evaluate the expression in the return line, while evaluating it in an
if (<*any boolean expression*>) {
return true;
} else {
return false;
}
structure is considered bad practice.

You have multiple issues in the code:
You are using this. in a static method: this. refers to the current instance of your class (the Calculate instance you're in), and static method belongs to the class, not the instance
You are referring to sumAddG() as a property member (in.SumAddG), which is wrong because SumAddG is a method.
In your example, you would use this. if you wish to call the method in your own class instance, but if you wish to call it on another instance in, then you would call it as in.sumAddG().
In static methods, you cannot use this because a static member does not belong to an instance, it belongs to the class, hence there is no recognition of this, as current instance does not exist.
However, if you have a method in the same class and you'd like to call it from a static method, the other method would have to be static as well, and you can call it as: Calculate.MyStaticMethod().
Had your method not been static, then this.sumAddG() == in.sumAddG() would actually compare the return value from calling sumAddG() in your instance, and sumAddG() on in instance.

The current state of your code (your edits are hard to follow) works as you probably expect.
this refers to the instance of the class you are in, so this.sumAddG()'s result uses the above fields current values. in.sumAddG() uses the fields of the instance in, which is specified as a parameter of the method same().
REMOTELY RELATED:
FYI, the use of this here is not needed, as its the default behaviour of the plain call sumAddG(). This means that your if statement could be:
if (sumAddG() == in.sumAddG()) { ... }

The this keyword refers to the current class you are in.
So in that example class you wrote, if you declare an instances variable, Calculate in. Then in the IF statement condition you would refer to it by putting the this keyword in front of it like: this.in
and to refer to the method's parameter by just calling:
in

The this keyword refers to an instance of the class you're using it in.
In the example you've shown this.sumAddG() would be referring to the method of an instance of the class Calculate. Since you're referring to a class instance you cannot use this from a static context.

this always refers to the class instance.
this.method() has nothing to do with the return value. some method have no values to return.
It mean: please compiler call this class instance membered method for
me.

Related

What happens to variables/objects in inner classes of function objects?

I have a function multi2 which returns inner class Inner as an Object.
What happens to a - where is it saved and how can I access it?
public class C {
private static Object multi2(final int a) {
class Inner {
public int hashCode() {
return 2*a;
}
}
return new Inner(); // What happens to a?
// Who allocates a?
// Can I Access a?
}
public static void main(String[] args) {
Object o = multi2(6);
System.out.println("o.hashCode() = " + o.hashCode());
o = multi2(4);
System.out.println("o.hashCode() = " + o.hashCode());
}
}
What happens at the implementation level is that a copy of the value of a is saved in a synthetic instance variable declared in the compiled version of the C.Inner class.
The value of a is passed to the compiled Inner constructor via an extra parameter.
The C.Inner.hashCode method uses the value of the synthetic variable. Accessing a in the source code of Inner.hashCode is transformed into accessing the corresponding synthetic variable in the compiled code.
The variable in the outer scope must be final1. The synthetic variable must be final2 in the Inner class. This maintains the illusion that (potentially) multiple instances of the Inner class are seeing the same a variable. (They aren't, but since the variable(s) can't be changed, it is not possible for the code of the inner class to tell the difference.)
If you use javap to look at the bytecodes for the compiled example, you will see the mechanisms used to implement this in the outer and the inner classes.
1 - or effectively final from Java 8 onwards.
2 - If a could be mutated by an Inner method, then two Inner instances with the same outer class need to share a mutable variable whose lifetime is (now) longer than the stackframe for a multi2 call. That entails somehow turning a from stack variable into something that lives on the heap. It would be expensive and complicated.
You have defined the class Inner inside the function so the scope of the class will be
restricted with in the method. And your function is static so it will be live as long as the class definition is loaded. You have override the hashCode function inside the InnerClass so every time you are calling the multi2(param) you are creating the hashCode for the instance of InnerClass and returning the instance of the InnerClass.
So as for you questions, please correct me if i am wrong.
What happens to a ?
a is with in the scope of your static method, so it will be live as long as the class definition is loaded.
Who allocates a?
scope of a is restricted inside the static method and static method does not require instance to access it but as for the static method/variable allocation, i think it depends on JVM.
Can I Access a?
No you cannot access a from outside you static method, it is restricted with in your static method.
Since the "a" is a local parameter, you could use a different approach to read the "a" value:
public class C {
public static Object multi2(final int a) {
return new Inner(a);
}
public static void main(String[] args) {
Object o = multi2(6);
System.out.println("o.hashCode() = " + o.hashCode());
System.out.println("o.getA() = " + ((Inner) o).getA());
o = multi2(4);
System.out.println("o.hashCode() = " + o.hashCode());
System.out.println("o.getA() = " + ((Inner) o).getA());
}
}
class Inner{
public int valueA;
public Inner(int a)
{
valueA = a;
}
public int getA() {
return valueA;
}
public int hashCode() {
return 2*valueA;
}
}
I wanted to know what was actually happening, so I compiled your code and looked at the bytecode output.
Basically what happens is the compiler adds in a constructor to your class 'Inner'. It also adds a single parameter to that constructor which takes 'a'. If your multi2() method was NOT static then there would probably also be a parameter to take 'this' where 'this' is the instance of 'C' that multi2() is executing on. BUT since we're in static context, there is no 'this'.
The compiler adds a private final field to your class 'Inner' and sets that private field using the value passed via the constructor. The compiler also converts
new Inner()
into
new Inner(a)
Hashcode then accesses the private field containing the value for a.
If 'a' was an object instead of a primitive, then it would be the same way, but a reference would be passed through instead of an actual number value.
How do you access this variable? Well you access it with reflections, but there are many problems:
1) You don't know the name of the field made by the compiler, so you can only get the name by looking at the bytecode. Don't trust decompilers as they might change the name. You gotta look at the bytecode yourself to find out.
2) The compiler probably marks the field as final, which means even if you can get reflections to access the field for you, you won't be able to update it.
3) It is entirely up to the compiler to figure out field names. Field names could change between builds depending on the compiler and it's mood.
Inner is a so called local class. a is a parameter passed to the method multi2 and accessable within that scope. Outside of that method, you cannot access a.

Calling a non-static method when trying to Implement an Interface using Java

I'm working on a simple calculator assignment where I need to use a Java Interface in the implementation of the code. I have set up the Interface as follows:
public interface OperationInterface {
// create symbolic constants to define operation options
static final int ADDITION = 1;
static final int SUBTRACTION = 2;
static final int MULTIPLICATION = 3;
static final int DIVISION = 4;
// return answer to requested calculation as a string
public String toString(int argumentOne, int argumentTwo);
}
I then have my 'Add' class as follows:
public class Add implements OperationInterface {
// override toString method by returning answer to calculation as a string
public String toString(int argumentOne, int argumentTwo)
{
return "" + (argumentOne + argumentTwo);
}
}
I am then trying to call this Add.toString() method from my client process as follows:
mOut.print(Add.toString(argumentOne, argumentTwo));
where mOut is an ActivityInterface. My current problem is that toString is underlined red in Android Studio with the error 'Non-static method toString(int, int) cannot be referenced from a static context. If I make the toString method static I get a different error in the Add class. I guess my approach is wrong so I'd appreciate some guidance.
Also, I would like to use my static final int's to determine which class to call, e.g. if (operation == ADDITION), then call Add.toString(int, int), and similar with a Subtract, Multiply and Divide class. I can't see a way to do that at present so again would really appreciate any guidance. Thanks
Your interface defines instance-specific behavior, but you're trying to call Add.toString as though it were a static method. It isn't, it's an instance method.
To use an instance method, you must have an instance:
Add a = new Add();
mOut.print(a.toString(argumentOne, argumentTwo));
Regarding choosing which operation to use based on an operation variable, I'd probably use a switch:
switch (operation) {
case ADDITION:
// ...
break;
case SUBTRACTION:
// ...
break;
//...and so on...
}
Remember to have a default clause.
There are other ways that might (or might not) be used in production code (using Map<Integer,OperationInterface>), but switch is probably the simplest, most straight-forward one for use in homework.
Being really careful not to actually do the homework here (as it would be a disservice to you, denying the learning opportunity), but you'd probably use the switch to create the instance, but not to do the actual call to toString. E.g., the code would be in very rough terms
Declare the variable with no initial value
Use switch to assign an appropriate instance to it
After the switch, call toString on it
That means the variable needs to be of type OperationInterface, not Add (or Subtract, etc.). Which is probably a big part of the point of the exercise.
Side note: Rather than concatenating with an empty string to convert an int to a string, e.g.
return "" + (argumentOne + argumentTwo);
consider String.valueOf(int), e.g.:
return String.valueOf(argumentOne + argumentTwo);
Your "toString" method is not static , so it cannot be called without creating an object for the class in which it is present.
Your code will work if the method "toString" was a static method, because static methods belong to the class and not the object, you can directly call it with the class name. That is why it says "Non-static method toString(int, int) cannot be referenced from a static context", because you are trying to access a method which is not static in a static way.
Create an object for the class and call the method you want from it.

How to use a Get method in java

A ton of questions have been asked on how to create getter and setter methods in java. But i have yet to see one that actually tells me how to use it.
Say i have Private int i = 1; in class A and i want to access it in class B.
I would first create a get method in class A called getIntI(); which would return the value of i.
Then in class B if i wanted to create an if statement that would need the value of i how would I get int i's value. The following is my try and calling the get method which does not work.
if(getIntI == 1)
{System.out.print.ln("int i is one");}
It is probably a really stupid question but i cant find an answer for it elsewhere.
In class A:
public int getIntI(){
return i;
}
Note: Now since your variable is single character named (just I), getter method is named getIntI since the name getI makes lesser sense. But generally, getter methods are something like get+VariableName and do not involve mentioning type. For example if I had a variable called int count, my method would be named getCount instead of getIntCount. Thats the general convention.
Also, naming variables in single char formats (like x, y etc) is discouraged because it may create confusion and management difficulty in complex programs. Though in very small programs they are fine.
Moving back to topic, if you want to access method getIntI() in class B, you will either have to inherit class A or create an object of class A reference to its method.
For class B:
Creating object
A obj = new A();
if(obj.getIntI() == 1)
// Do stuff
Inheriting class A:
public class B extends A{
... // Your stuff
if(getIntI() == 1)
// Do stuff
... // Your stuff
}
Of course there are other ways but these are simpler ones.
if class B extends class A then do only this changes,
if(getIntI() == 1)
If above inheritance was not there then do this,
if(new A().getIntI() == 1)
The problem is that you need to create a object derived from class A before you can access its variables/methods using
A a = new A();
where "a" is the name of the object. Then you can access the getter method by calling a.getIntI. You can also declare the int variable as static so that you wouldn't have to instantiate any objects. An example of class A with the static variable and getter method would be:
public class A {
private static int i = 1;
public static int getIntI() {
return i;
}
}
With this, you can call the getter method with A.getIntI().
First, if you want to access one of A's non-static methods (in this case, getIntI), you need an instance of A, or you can just declare it static.
Secondly, A method call needs a parameter list, even an empty one is needed. getIntI does not need any parameters, so you should add () at the end.
Now, you can get an instance of A somewhere and call it aObj. Andd then you can use it in the if statement:
if (aObj.getIntI == 1)
And remember to add ()!
if (aObj.getIntI() == 1)
Alternatively, you can declare i in A as static. There are two main differences between a static and a non-static variable.
You don't need an instance of the declaring class to access the static variable.
Unlike non-static variables, there is only one static variable. If you have a non-static variable i, you can create lots of instances of A and each instance will have its own i
Now let's see this in action, declare i as static:
public class A {
private static int i = 1;
public static int getIntI () { return i; }
}
Note how both i and getIntI are declared static.
Then you can use in a if statement like this:
if (A.getIntI() == 1)
Note how I use the class name A to access the method, not an instance of A.

different signatures for accessing class methods

I really am a little confused here. Normal signature to call accessible class method or variable is (Class/Object).(method/variable). Then how do we give System.out.println()? Since System.out only gives the return type but does not belong to same class. Also in servlets, "this.getServletConfig().getInitParameter("defaultUser")" is not making sense to me, since getServletConfig() and getInitParameter are both member functions of same class, so signature becomes something like, class.method1().method2(), where method1 and method2 are member functions of same class. Can someone please explain..
Example:
Class CascMethodClassB()
{
public CascMethodClassA methodTest()
{
CascMethodClassA obj1 = new CascMethodClassA();
return obj1;
}
} /*Class CascMethodClassB ends*/
Class CascMethodClassA()
{
public int varTest;
public CascMethodClassA()
{
varTest = 7;
}
} /*Class CascMethodClassA ends*/
Class CascMethodClassC()
{
CascMethodClassB obj2 = new CascMethodClassB();
int varTestC = obj2.methodTest().varTest
public static void main(String[] args)
{
System.out.println("varTest in CascMethodClassA is: "+ varTestC);
} /*Class CascMethodClassC ends*/
}
Thankyou,
Fraggy.
Both are different cases.
In the first case, outis a public static member in the System class. The member out is of type PrintStream, so the call
System.out.println()
will call the method println() from the PrintStream object (out).
The second case, is something called method chaining. What happens is that class.method1() will return an object instance, according to Java docs it will return a ServetConfig object. So, you can again call a method from that returned object. Another way of seeing that call is (brackets are redundant, just there so you can visualize the order of the calls):
(ClassName.someMethod1()).someMethod2();
System.out is a public class variable of type PrintStream, not a
method. Therefore you can invoke the println method on it, which returns void.
this.getServletConfig().getInitParameter("defaultUser") makes
perfect sense once you understand chaining method invocations. In
this case, you are:
calling the present instance of Servlet
getting its instance field's value of type ServletConfig
getting whichever String value is returned by invoking the getInitParameter method on the ServletConfig object
Finally, a method's signature is made of the method's name and parameter types
Each non-void method returns a type, which may be a different type to the declaring class, so the chained method/field will have the methods of the returned type (not the class it's called from or the class that the first method is defined in).
For example, to break down System.out.printkln():
System.out // out is a public field of type PrintStream
.println() // println() is a method of PrintStream, not System

Changing the value of an object in a method changes it globally?

Here's my Code
Class A
public class A {
private int a;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
Class Change
public class Change {
public void changeSomething(A a){
a.setA(13);
}
}
Class Learn
public class Learn {
public static void main(String[] args) {
A a = new A();
Change change = new Change();
change.changeSomething(a);
System.out.println(a.getA());
}
}
The output is 13. Now when i am passing an object to the changeSomething method, internally the value of Object A has been changed but why do i see this effect outside that function?
Is not this equivalent to passing by value in C where unless you return that variable/Object you dont get the updated value.
i.e. dont i need to do a=changeSomething(a); and set the return type of this method to be as A?
Thanks
You're passing a reference to the original object around. When you write a method
void someMethod(A param) { ... }
param is a reference to the original object. The original object isn't being copied. Consequently when you change this object, the change is visible wherever that object is observed.
When you write:
private A a = new A();
it's important to realise that the variable is a reference to object type A, not an actual object type A. It's a fine distinction, granted.
The above behaviour can cause unexpected effects across your system, and it's an argument for immutability, especially in threaded environments where changes can be triggered from multiple threads.
Short:
changeSomething() will update the value for object so if you refer to same instance you will get the same value back
Bit long explanation:
//an Object of A created and its reference is set to a
A a = new A();
//instance of Change is created and its reference is set to change
Change change = new Change();
//it passes reference's (a) 's value to the changeSomething method
//which invokes `setA()` on instance referred by a (which is the same instance that waas crated in line 1
change.changeSomething(a);
//so you will get the changed value here
System.out.println(a.getA());
Well the code you provided works directly on an instance of A. This instance is changed, no matter if you return it or not. Its still the same instance of your object. And this instances variable reflects the new value.
This is because you pass the Object, and objects in Java are always passed by reference. Only primitive (int, double, char, long...) are passed by value.
In C it could be:
public void changeSomething(A& a){
a.setA(13);
}

Categories

Resources