public class Outer {
public void Say(Bar bar) {
//...
}
public Outer(final Foo foo) {
//...
}
}
public interface Foo {
void blah(Bar bar);
}
public class Application {
public static void main(String[] args) {
Outer outer = new Outer(new Foo() {
#Override
public void blah(Bar bar) {
/*trying to access "outer"*/.Say(bar);
}
});
}
}
What should I do to access "outer"?
Thanks.
StackOverflow forbade me from posting this because it said my post was mainly code and this line is just a bunch of nonsense. Please ignore it.
Outer is not reachable. As the instance is created after Foo is created.
I see two ways:
1. Convert the variable outer into a static context.
2. Hand over the variable while calling method blah()
In your example, 'outer' is simply 'this'
Related
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();
}
}
This is simple Abstraction demo code where i am not able to create a object of suresh class can someone help me out what is going wrong here
public class AbstractionDemo {
public static void main(String[] args) {
Mahesh obj= new Suresh();
obj.call();
obj.cook();
obj.dance();
obj.move();
}
abstract class Mahesh{
public void call()
{
System.out.println("Calling");
}
public abstract void move();
public abstract void dance();
public abstract void cook();
}
abstract class Ramesh extends Mahesh {
public void move()
{
System.out.println("Moving");
}
}
class Suresh extends Ramesh{
public void dance()
{
System.out.println("dancing");
}
public void cook()
{
System.out.println("Cooking");
}
}
}
At Mahesh obj= new Suresh(); I am getting below error
No enclosing instance of type AbstractionDemo is accessible. Must qualify the allocation with an enclosing instance of type AbstractionDemo (e.g. x.new A() where x is an instance of AbstractionDemo)
You cannot create an inner class object without creating an instance of outer class. Read the docs
Suresh obj = new AbstractionDemo().new Suresh();
obj.dance(); // Whatever methods you have
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();
}
}
I want to be able to subclass some values in an enum, in order that I don't have to repeat code too much. Is there some way I can do this? Here's an example of what I want to achieve, which Eclipse quickly tells me is an abomination:
public enum Foo {
BAR {
#Override
public void taskA() {
System.out.println("A");
}
#Override
public void taskB() {}
},
BAZ extends BAR {
#Override
public void taskB() {
System.out.println("B");
}
};
public abstract void taskA();
public abstract void taskB();
}
BAR would have only the implementation of taskA and an empty taskB, and BAZ would have both methods - BAR's implementation of taskA, and its own implementation of taskB.
I'm not changing the values of the enum after it's declared, so why doesn't this work? I could call BAR's taskA method within BAZ, so why can't I do this?
I want to be able to subclass some values in an enum, in order that I
don't have to repeat code too much.
The usual way to share code among constant-specific methods is to declare a private static method (either in the enum itself or in a utility helper class) which contains the common code that you wish to access from your constant-specific methods.
For example ...
public enum Foo {
BAR {
#Override
public void taskA() {
commonToTaskAandB();
System.out.println("B");
}
#Override
public void taskB() {}
},
BAZ {
#Override
public void taskB() {
commonToTaskAandB();
System.out.println("B");
}
};
public abstract void taskA();
public abstract void taskB();
private static void commonToTaskAandB() {
// shared code here
:
:
}
}
Note that the code "BAZ extends Bar" is illegal because BAZ is not a type. BAZ is an instance of your Enum<Foo> type. An instance cannot extend another type. It is incorrect to apply object-oriented principles like inheritance to enum constants because, in Java, enum constants are instances of a class and not classes themselves.
Enum-Constants are objects (instances), not classes. You can only subclass classes.
However even that will not work: you can only extend enums with anynomous inner classes.
You will have to find another solution for your use case. You could:
use a static method for the shared code
call BAR.taskA() in BAZ
make taskA not abstract and put your code there
use normal constants, instead of enums
But my favorit is:
inject behaviour instead of overriding!
Example code:
class Behavior {
public static Runnable A = new Runnable() {
public void run() {
System.out.println("A");
}
}
public static Runnable B = new Runnable() {
public void run() {
System.out.println("B");
}
}
public static Runnable DO_NOTHING = new Runnable() {
public void run() {
}
}
}
public enum Foo {
BAR(Behavior.A, Behavior.DO_NOTHING),
BAZ(Behavior.A, Behavior.B);
private final Runnable mechanismA;
private final Runnable mechanismB;
private Foo(Runnable mechanismA, Runnable mechanismB) {
this.mechanismA = mechanismA;
this.mechanismB = mechanismB;
}
public void taskA() {
mechanismA.run;
}
public void taskB() {
mechanismB.run;
}
}
Pros of this solution:
The code explicitly defines the behavior of each enum constant - no implicit calculations => easier to read
You can use inheritance, etc in the Behavior-class
You can easily switch behaviorA and behaviorB - or reuse that code anywhere else
If you have Java8 available you can even shorten the code to this:
public static Runnable A = () -> {
System.out.println("A");
};
In the code below, when I run Test2, why does it print null instead lol? It seems that the config method modifies the a property of class Test instead of Test2.
But what's the meaning of inheriting the public methods which manipulate private properties then, why did they design Java like this?
EDIT:
Class Test shall not be modified. What I want to do is to reuse the config method. I define a private property a for Test2, but config just ignores it and uses the one of Test. Shouldn't a method use the property of the class it is in instead of that of the inherited super class?
public class Test {
private String a;
public void config() {
a = "lol"
}
}
public class Test2 extends Test {
private String a;
public void print() {
config();
System.out.println(a);
}
public static void main(String[] args) {
print()
}
}
The purpose is, in short, encapsulation. You don't need to, and can't, access something that is private from outside of the class. The accepted pattern of doing what you want is with getters/setters:
public abstract class Test {
public void config() {
setA("lol");
}
public abstract void setA(String value);
}
public class Test2 extends Test {
private String a;
public void setA(String value) {
a = value;
}
public void print() {
config();
System.out.println(a);
}
public static void main(String[] args) {
new Test2().print();
}
}
It seems that the config method modifies the a property of class Test instead of Test2.
That's right.
why does it print null instead lol?
You have two variables with the same name. One is in the superclass Test, another is in the subclass Test2. Both are named a but they refer to different things.
The method config() in the superclass references the superclass a and the print() method in the subclass references the subclass a. Since the variables are private, neither method can see the variable in the other class.
why did they design Java like this?
This is the nature of private. Nobody else can see it.
It looks to me like you actually desired the behavior of a protected variable:
public class Test {
protected String a;
public void config() {
a = "lol"
}
}
public class Test2 extends Test {
public void print() {
config();
System.out.println(a);
}
public static void main(String[] args) {
new Test2().print();
}
}
This will print lol.