What is this Java method being called on? - java

Alright, so I am new to Java and have a quick question for anyone who would be nice enough to answer it.
What object is this doSomething method called on? Is it the same as calling this.doSomething()?
public class Something{
public void doSomething(){
System.out.println("Something is done");
}
public Something(){
//what object is this being called on?
doSomething();
}
public static void main(String[] args){
Something foo = new Something();
}
}
Any help is appreciated!

Yes, doSomething is defined within the Something class. Therefore, that is the same as this.doSomething().
To call the doSomething() (declared within "Something" class) from outside the class, you would need to call it like so:
public static void main(String[] args){
Something foo = new Something();
foo.doSomething();
}

Yes. Calling this.doSomething is same as calling doSomething(). Not sure what GUI are using. For example if you use Eclipse and have the below code and you click on doSomething it will take you to the void doSomething method. using this is just a reference to the current instance. More details can be found regarding this http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
public class Something{
public void doSomething(){
System.out.println("Something is done");
}
public Something(){
//what object is this being called on?
this.doSomething();
}
public static void main(String[] args){
Something foo = new Something();
}
}

what object is this being called on?
The reference which is going to be assigned to foo, in the scope of the constructor it is the this reference. And yes, doSomething(); (in this context) is equivalent to this.doSomething();
We can see this is the case by adding a UUID to Something (and displaying it in doSomething),
public Something() {
uuid = UUID.randomUUID().toString();
doSomething();
}
private final String uuid;
public void doSomething() {
System.out.println(uuid);
}
and then calling doSomething() again in main like
public static void main(String[] args) {
Something foo = new Something();
foo.doSomething();
}
And you'll get the same UUID twice.

Related

Inline Java method defined for a class is not available when calling the object [duplicate]

Is there any Java syntax to access new methods defined within anonymous inner classes from outer class? I know there can be various workarounds, but I wonder if a special syntax exist?
For example
class Outer {
ActionListener listener = new ActionListener() {
#Override
void actionPerformed(ActionEvent e) {
// do something
}
// method is public so can be accessible
public void MyGloriousMethod() {
// viva!
}
};
public void Caller() {
listener.MyGloriousMethod(); // does not work!
}
}
MY OWN SOLUTION
I just moved all methods and members up to outer class.
Once the anonymous class instance has been implicitly cast into the named type it can't be cast back because there is no name for the anonymous type. You can access the additional members of the anonymous inner class through this within the class, in the expression immediate after the expression and the type can be inferred and returned through a method call.
Object obj = new Object() {
void fn() {
System.err.println("fn");
}
#Override public String toString() {
fn();
return "";
}
};
obj.toString();
new Object() {
void fn() {
System.err.println("fn");
}
}.fn();
identity(new Object() {
void fn() {
System.err.println("fn");
}
}).fn();
...
private static <T> T identity(T value) {
return value;
}
A student in my class asked our professor if this could be done the other day. Here is what I wrote as a cool proof of concept that it CAN be done, although not worth it, it is actually possible and here is how:
public static void main(String[] args){
//anonymous inner class with method defined inside which
//does not override anything
Object o = new Object()
{
public int test = 5;
public void sayHello()
{
System.out.println("Hello World");
}
};
//o.sayHello();//Does not work
try
{
Method m = o.getClass().getMethod("sayHello");
Field f = o.getClass().getField("test");
System.out.println(f.getInt(o));
m.invoke(o);
} catch (Exception e)
{
e.printStackTrace();
}
}
By making use of Java's Method class we can invoke a method by passing in the string value and parameters of the method. Same thing can be done with fields.
Just thought it would be cool to share this!
Your caller knows listener as an ActionListener and therefore it doesn't know anything about that new method. I think the only way to do this (other than doing reflection gymnastics, which really would defeat the purpose of using an anonymous class, i.e. shortcut/simplicity) is to simply subclass ActionListener and not use an anonymous class.
Funny enough, this is now allowed with var construct (Java 10 or newer). Example:
var calculator = new Object() {
BigDecimal intermediateSum = BigDecimal.ZERO;
void calculate(Item item) {
intermediateSum = Numbers.add(intermediateSum, item.value);
item.sum= intermediateSum;
}
};
items.forEach(calculator::calculate);
Here with method reference, but works with dot method call as well, of course. It works with fields as well. Enjoy new Java. :-)
I found more tricks with var and anonymous classes here: https://blog.codefx.org/java/tricks-var-anonymous-classes/
No, it's imposible. You would need to cast the ActionListener to its real subclass name, but since it's anonymous, it doesn't have a name.
The right way to do it is using reflection:
import java.lang.reflect.InvocationTargetException;
public class MethodByReflectionTest {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Object obj = new Object(){
public void print(){
System.out.println("Print executed.");
}
};
obj.getClass().getMethod("print", null).invoke(obj, null);
}
}
You can check here: How do I invoke a Java method when given the method name as a string?
Yes you can access the method see the example below if any doubt please comment
package com;
interface A
{
public void display();
}
public class Outer {
public static void main(String []args)
{
A a=new A() {
#Override
public void display() {
System.out.println("Hello");
}
};
a.display();
}
}

Adding a method to a class using anonymous class [duplicate]

Is there any Java syntax to access new methods defined within anonymous inner classes from outer class? I know there can be various workarounds, but I wonder if a special syntax exist?
For example
class Outer {
ActionListener listener = new ActionListener() {
#Override
void actionPerformed(ActionEvent e) {
// do something
}
// method is public so can be accessible
public void MyGloriousMethod() {
// viva!
}
};
public void Caller() {
listener.MyGloriousMethod(); // does not work!
}
}
MY OWN SOLUTION
I just moved all methods and members up to outer class.
Once the anonymous class instance has been implicitly cast into the named type it can't be cast back because there is no name for the anonymous type. You can access the additional members of the anonymous inner class through this within the class, in the expression immediate after the expression and the type can be inferred and returned through a method call.
Object obj = new Object() {
void fn() {
System.err.println("fn");
}
#Override public String toString() {
fn();
return "";
}
};
obj.toString();
new Object() {
void fn() {
System.err.println("fn");
}
}.fn();
identity(new Object() {
void fn() {
System.err.println("fn");
}
}).fn();
...
private static <T> T identity(T value) {
return value;
}
A student in my class asked our professor if this could be done the other day. Here is what I wrote as a cool proof of concept that it CAN be done, although not worth it, it is actually possible and here is how:
public static void main(String[] args){
//anonymous inner class with method defined inside which
//does not override anything
Object o = new Object()
{
public int test = 5;
public void sayHello()
{
System.out.println("Hello World");
}
};
//o.sayHello();//Does not work
try
{
Method m = o.getClass().getMethod("sayHello");
Field f = o.getClass().getField("test");
System.out.println(f.getInt(o));
m.invoke(o);
} catch (Exception e)
{
e.printStackTrace();
}
}
By making use of Java's Method class we can invoke a method by passing in the string value and parameters of the method. Same thing can be done with fields.
Just thought it would be cool to share this!
Your caller knows listener as an ActionListener and therefore it doesn't know anything about that new method. I think the only way to do this (other than doing reflection gymnastics, which really would defeat the purpose of using an anonymous class, i.e. shortcut/simplicity) is to simply subclass ActionListener and not use an anonymous class.
Funny enough, this is now allowed with var construct (Java 10 or newer). Example:
var calculator = new Object() {
BigDecimal intermediateSum = BigDecimal.ZERO;
void calculate(Item item) {
intermediateSum = Numbers.add(intermediateSum, item.value);
item.sum= intermediateSum;
}
};
items.forEach(calculator::calculate);
Here with method reference, but works with dot method call as well, of course. It works with fields as well. Enjoy new Java. :-)
I found more tricks with var and anonymous classes here: https://blog.codefx.org/java/tricks-var-anonymous-classes/
No, it's imposible. You would need to cast the ActionListener to its real subclass name, but since it's anonymous, it doesn't have a name.
The right way to do it is using reflection:
import java.lang.reflect.InvocationTargetException;
public class MethodByReflectionTest {
public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Object obj = new Object(){
public void print(){
System.out.println("Print executed.");
}
};
obj.getClass().getMethod("print", null).invoke(obj, null);
}
}
You can check here: How do I invoke a Java method when given the method name as a string?
Yes you can access the method see the example below if any doubt please comment
package com;
interface A
{
public void display();
}
public class Outer {
public static void main(String []args)
{
A a=new A() {
#Override
public void display() {
System.out.println("Hello");
}
};
a.display();
}
}

Is there a way to run a Method in a method that does not come from the class where this method is?

Basicly what i am asking is this:
public void RunMe(Method method){
}
so basicly i mean if i can run the Method called "method" from that Method called RunMe(Method....
Use a Method as an argument isn't the right way.
Hum the best way (I think) to do something like that is to use the reflection.
Example:
public void RunMe(Object target, String methodName){
Class c = target.getClass();
Method m = c.getMethod(methodName, new Class[0]);
m.invoke(target, new Object[0]);
}
If you need more details about it you can check here.
If you want to access a method outside its class, the method cannot be a private method. If you don't know what private, public, static, etc. is, read about access-level modifiers.
Let's say that you have a class called MyClass with a method called myMethod, and your main() in a class called MainClass then you would do it like this:
class MyClass {
static void myMethod() {
System.out.println("Testing");
}
}
public class MainClass {
public static void main(String[] args) {
foo();
}
void foo() {
MyClass.myMethod();
}
}
myMethod has to be static if you want to reach the method without creating an object of MyClass. However, you might dislike static and have no problem with creating an object. In that case, do something like this:
class MyClass {
void myMethod() {
System.out.println("Testing");
}
}
public class MainClass {
public static void main(String[] args) {
foo();
}
void foo() {
MyClass a = new MyClass();
a.myMethod();
}
}

Universal main method with this.getClass().newInstance()

Okay, so don't ask why, but I'm trying to make a universal public static void main() method. I've already tried to use these two methods;
public class Foo {
public static void main(String[] args){
try {
this.getClass().newInstance().check();
} catch(Exception e) {
e.printStackTrace();
}
}
public void check() {
System.out.println("Check succesful");
}
}
The error I get is that this "Cannot be used in a static context"
Okay, so I know I can't use this in a static context, but what I want to know is how I can replace it, without using Foo.check()
If possible, how should I do this? If not, I'd like to know why.
Looking at How to call getClass() from a static method in Java? and Getting the class name from a static method in Java something like
interface Checkable {
public void check();
}
public class Foo implements Checkable {
public static void main(String[] args){
try {
Class currentClass = new Object() { }.getClass().getEnclosingClass();
Checkable instance = (Checkable) currentClass.newInstance();
instance.check();
} catch(Exception e) {
e.printStackTrace();
}
}
public void check() {
System.out.println("Check succesful");
}
}
might do the trick, but I'm not sure I should recommend doing that...
this is the current instance. You don't have an instance in a static method. Please see I want to know the difference between static method and non-static method
Do this instead:
public class Foo {
public static void main(String[] args) {
new Foo().check();
}
public void check() {
System.out.println("Check succesful");
}
}
As an answer to the comment (I don't seem to be able to make comments yet): No. The only other way is to make check() static as well and call Foo.check(), but you didn't want to do that.
There's no this in a static context; that's exactly what static means. The approach you're trying will not work. You could perhaps supply the name of the class you're interested in on the command line.
As, I know in java instance variable cannot be accessed in static block util you don't have object of that class for which class you want to access instance variable and this in java is a instance variable. so you cannot access this variable in any static block or you required object reference for this.for further clarification check here.
why dont you try this ?
public class Foo
{
public static void main(String[] args){
try
{
Foo obj = new Foo();
// this.getClass().newInstance().check();
obj.check();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void check()
{
System.out.println("Check succesful");
}
}

static initialization in interface

When I tried to write something like this:
public interface MyInterface {
static {
System.out.println("Hello!");
}
}
the compiler could not compile it.
But when I wrote something like this:
interface MyInterface {
Integer iconst = Integer.valueOf(1);
}
and decompiled it, I saw static initialization:
public interface MyInterface{
public static final java.lang.Integer i;
static {};
Code:
0: iconst_1
1: invokestatic #1; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4: putstatic #2; //Field i:Ljava/lang/Integer;
7: return
}
Could you please explain this behavior to me?
Interfaces should not have side-effects and that even applies to static intializers. They would have highly JVM-implementation dependent behavior. Look at the following code
public class InterfaceSideEffects {
public static void main(String[] args) {
System.out.println("InterfaceSideEffects.main()");
Impl i=new Impl();
System.out.println("Impl initialized");
i.bla();
System.out.println("Impl instance method invoked");
Foo f=new Impl();
System.out.println("Impl initialized and assigned to Foo");
f.bla();
System.out.println("Foo interface method invoked");
}
}
interface Foo {
int dummy=Bar.haveSideEffect();
void bla();
}
class Bar {
static int haveSideEffect() {
System.out.println("interface Foo initialized");
return 0;
}
}
class Impl implements Foo {
public void bla() {
}
}
What do you think, when will interface Foo initialized be printed? Try to guess and run code afterwards. The answer might surprise you.
You can have static initialisation, but you cannot have a static block. The fact the static initialisation needs a static code block to implement does change the Java syntax.
The point is you are not meant to have code in an interface (before Java 8) but you are allowed to initialise fields.
BTW you can have a nested class or enum which has as much code as you like and you can call this while initialising a field. ;)
You can get around the problem - if you see it as a problem - by putting a second non-public class in the same file.
public interface ITest {
public static final String hello = Hello.hello();
}
// You can have non-public classes in the same file.
class Hello {
static {
System.out.println("Static Hello");
}
public static String hello() {
System.out.println("Hello again");
return "Hello";
}
}
Testing this with:
public class Test {
public void test() {
System.out.println("Test Hello");
System.out.println(ITest.hello);
}
public static void main(String args[]) {
try {
new Test().test();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
}
prints:
Test Hello
Static Hello
Hello again
Hello
Java is such a clever language - it makes it difficult to do stupid things but not impossible. :)
Intefaces does not have any initialization blocks. Following code snippet may be helpful..
public interface MyInterface {
public static final int a;// Compilation error as there is no way for
// explicit initialization
}
public class MyClass {
public static final int a;// Still no error as there is another way to
//initialize variable even though they are final.
static{
a=10;
}
}
There is never a point to declaring a static method in an interface. They cannot be executed by the normal call MyInterface.staticMethod(). (EDIT:Since that last sentence confused some people, calling MyClass.staticMethod() executes precisely the implementation of staticMethod on MyClass, which if MyClass is an interface cannot exist!) If you call them by specifying the implementing class MyImplementor.staticMethod() then you must know the actual class, so it is irrelevant whether the interface contains it or not.
More importantly, static methods are never overridden, and if you try to do:
MyInterface var = new MyImplementingClass();
var.staticMethod();
the rules for static say that the method defined in the declared type of var must be executed. Since this is an interface, this is impossible.
You can of course always remove the static keyword from the method. Everything will work fine. You may have to suppress some warnings if it is called from an instance method.
To answer some of the comments below, the reason you can't execute "result=MyInterface.staticMethod()" is that it would have to execute the version of the method defined in MyInterface. But there can't be a version defined in MyInterface, because it's an interface. It doesn't have code by definition.

Categories