How to access anonymous inner class in main method? - java

How to access the anonymous inner class object in main method. It is giving compile time error saying that "cannot make static reference to non static method". If I am making anonymous inner class as static then I can access ut I want to access without making it static.
How to do that. Please help.
AnonymousInnerClass2.java
abstract class AnonymousInnerClass21
{
abstract void m();
}
public class AnonymousInnerClass2
{
AnonymousInnerClass21 a=new AnonymousInnerClass21()
{
#Override
void m() {
System.out.println("Hello");
}
};
public static void main(String[] args)
{
a.m();
}
}

this is because for accessing inner class (whether its is normal/named class or Anonymous class), you must create object of class in which inner class is defined, you can try below
abstract class AnonymousInnerClass21
{
abstract void m();
}
public class AnonymousInnerClass2
{
AnonymousInnerClass21 a=new AnonymousInnerClass21()
{
#Override
void m() {
System.out.println("Hello");
}
};
public static void main(String[] args)
{
AnonymousInnerClass2 anonymousInnerClass2= new AnonymousInnerClass2 ();//create outer class object
anonymousInnerClass2.a.m(); // access inner class object through outer class object
}
}

Related

Why can I access overridden subclass methods from the superclass? [duplicate]

This question already has answers here:
Java superclass calls subclass method
(5 answers)
Closed 1 year ago.
Why does method() call the overridden subclass method2 instead of method2 in the BaseClass?
public class BaseClass {
public void method(){
System.out.println("method() called");
method2();
}
public void method2(){
System.out.println("method2() called");
}
}
public class ChildClass extends BaseClass {
public void method2(){
System.out.println("method2() from BaseClass");
}
}
public class Main {
public static void main(String[] args) {
ChildClass obj = new ChildClass();
obj.method();
}
}
This is the concept of Runtime polymorphism (Dynamic Method Dispatch). Because you are assigning the object (instance) of ChildClass to obj reference variable, it will call the method of child class.
Always the method of the class whose instance is created gets called first. If that method is not present in that particular child class, then the parent's inherited method gets called.
If you come from the C++ corner:
all instance methods (non-static) in Java are virtual.
All class methods (static) are NOT.
This is why your case happens.
This is also, why the Java compiler will complain (warn) that if you access a static method via an object, that you should call via the distinct class, because calls to the "static method of a object" could be ambiguous, because it could be two static methods with the same signature that get called.
Extending your Example:
package stackoverflow.staticcalls;
public class BaseClass {
public void method() {
System.out.println("method() called");
method2();
}
public void method2() {
System.out.println("method2() called");
}
static public void sayHello() {
System.out.println("BaseClass.sayHello()");
}
}
and
package stackoverflow.staticcalls;
public class ChildClass extends BaseClass {
public void method2() { // compiler warning: The method method2() of type ChildClass should be tagged with #Override since it actually overrides a superclass method
System.out.println("method2() from BaseClass");
}
public void originalCallToBaseMethod2() {
super.method2(); // will run BaseClass.method2()
}
static public void sayHello() {
System.out.println("ChildClass.sayHello()");
}
}
and
package stackoverflow.staticcalls;
public class Main {
public static void main(final String[] args) {
final ChildClass obj = new ChildClass();
System.out.println("\nCalling obj.method(); ...");
obj.method();
System.out.println("\nCalling obj.sayHello(); ...");
obj.sayHello(); // compiler warning: The static method sayHello() from the type ChildClass should be accessed in a static way
System.out.println("\nCalling ChildClass.sayHello(); ...");
ChildClass.sayHello(); // the proper call
System.out.println("\nCalling BaseClass.sayHello(); ...");
BaseClass.sayHello(); // but you can also explpicitly call the other method
System.out.println("\nCalling obj.originalCallToBaseMethod2(); ...");
obj.originalCallToBaseMethod2(); //
}
}
Here you see the examples to what I said.
Note: In the last call in Main.main() we still can call BaseClass.method2(), but not directly. We have to be within ChildClass to do that, and it's done via the super keyword/reference.
A little off-topic note, to complete addressing patterns:
If you're inside an inner class and need to call to a overshadowed name in the outer class, you can use Outer.this.method():
package stackoverflow.staticcalls;
import stackoverflow.staticcalls.OuterInner.Outer.Inner;
public class OuterInner {
class Outer {
void method() {
System.out.println("OuterInner.Outer.method()");
}
class Inner {
void method() {
System.out.println("OuterInner.Outer.Inner.method()");
}
void callOuter() {
Outer.this.method();
}
}
}
public static void main(final String[] args) {
final OuterInner oi = new OuterInner();
final Outer outer = oi.new Outer();
final Inner inner = outer.new Inner();
System.out.println("\nCalling inner.method(); ...");
inner.method();
System.out.println("\nCalling inner.callOuter(); ...");
inner.callOuter();
}
}

Ways to call method local inner class from outside [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
public class OuterMain {
public static void main(String[] args) {
Outer outer = new Outer();
outer.m2();
}
}
class Outer {
public void m1() {
class Inner {
void display() {
System.out.println("msg is displayed");
}
}
Inner inn = new Inner();
//cannot write code to call display() here
}
public void m2() {
//inner.display();
}
}
Above is the code block where there is a method local inner class. The display method inside the inner class prints a message. The main class creates an instance of Outer and calls m2(). I was asked to do modification, apply any concept in java but the task is to call the Inner class' display() method from m2(). Only restriction is that the method cannot be made static.
One thing you can do is use a private interface and make Inner implement it, thus enabling m2() to return an object with a display() method that can be called elsewhere in the same outer class
class Outer {
public Displayable m1() {
class Inner implements Displayable {
#Override
public void display() {
System.out.println("msg is displayed");
}
}
return new Inner();
}
private interface Displayable {
void display();
}
public void m2() {
m1().display();
}
}
There are three issues here
The type Inner is not visible to m2()
The instance of Inner created in m1() is not visible to m2()
The method m1() is never invoked.
The purpose of local classes is precisely to reduce the visibility of the class and its instances and to avoid creating the instances when the method has not been invoked. Even the initialization of Inner should be deferred until the method m1() creates the first instance of it.
A solution not perverting those properties would be
class Outer {
private Runnable accessor;
public void m1() {
class Inner {
void display() {
System.out.println("msg is displayed");
}
}
Inner inn = new Inner();
accessor = inn::display;
}
public void m2() {
m1();
accessor.run();
}
}
Here, m1() doesn't invoke display but provides access to it using a standard interface, without giving away any information about its internals. m2() invokes the method m1() to get the access followed by invoking the standard interface method.
In Java, we can write a class within a method and this will be a local type. Like local variables, the scope of the inner class is restricted within the method.
A method-local inner class can be instantiated only within the method where the inner class is defined. The following program shows how to use a method-local inner class
instantiate the class at proper point.
I will show you the code*
package com;
public class Outer{
public void m1() {
class Inner {
public void display(){
System.out.println("display from inner class");
}
}// end of inner class
// Accessing the inner class
Inner inner = new Inner();
inner.display();
}//m1 ends here
public static void main(String[] args) {
Outer outer=new Outer();
outer.m1();
}
}
With the help of interface the inner class method can be access as per your requirement :
class OusterMain{
public static void main(String[] args) {
OuterClass oc = new OuterClass();
oc.methodTwo();
}
}
class OuterClass {
public InnerInterface methodOne() {
class InnerClass implements InnerInterface{
#Override
public void display() {
System.out.println("Print message.");
}
}
// this reference is used to call display() method inside methodTwo()
return new InnerClass();
}
private interface InnerInterface{
void display();
}
public void methodTwo() {
methodOne().display();
}
}
Using reflection you can achieve this goal easily.
Here com.problem.solution is my package name. Replace it with your package name.
Get the outer and inner class object associated with the class or interface with the given string name.
Like - forName("com.problem.solution.Outer");
Then try to access inner class using - Class.forName("com.problem.solution.Outer$1Inner");
In java reflection, you can access any inner class using OuterClass$1InnerClass this type of syntax.
Then construct object, then pick your desired method and then invoke that method.
Complete code:
//package com.problem.solution;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class OuterMain {
public static void main(String[] args) {
Outer outer = new Outer();
outer.m2();
}
}
class Outer {
public void m1() {
class Inner {
void display() {
System.out.println("msg is displayed");
}
}
Inner y = new Inner();
}
public void m2() {
try {
Class<?> enclosingClass = Class.forName("com.problem.solution.Outer");
Object enclosingInstance = enclosingClass.newInstance();
Class<?> innerClass = Class.forName("com.problem.solution.Outer$1Inner");
Constructor<?> ctor = innerClass.getDeclaredConstructor(enclosingClass);
Object innerInstance = ctor.newInstance(enclosingInstance);
Method someMethod = innerInstance.getClass().getDeclaredMethod("display");
someMethod.setAccessible(true);
someMethod.invoke(innerInstance);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Output:
msg is displayed

What are the 3 different contexts a class can be declared?

I am told there are three different contexts in which a class can be declared in Java.
It has to do with the location within a program, but I can't think of what they are.
Obviously a class can be declared at the top of a page, the only other example I can think of is like a nested class?
I feel I may be going about this the wrong way.
In a package
package com.example.mypackage;
public class TheClass {
}
In a class
package com.example.mypackage;
public class OuterClass {
class InnerClass {
}
}
Anonymously
public class MainClass {
public static void main(String[] args) {
AbstractClass myObject = new AbstractClass() {
// overrides and other fields of the
// anonymous class goes in this block
};
}
}
EDIT: As #daniu stated in the comment, a class can also be created in a method:
public class MainClass {
public static void main(String[] args) {
class MethodClass {
}
MethodClass myObject = new MethodClass();
}
}
There are actually 4 distinct syntactic contexts:
In the "compilation-unit" context; i.e. a top-level class declaration.
package foo;
public class Bar{}
As a nested class declaration in a class declaration.
package moo;
public class Cow {
public class Inner {}
}
As a nested class declaration in a method declaration.
package too;
public class Far {
public void test() {
class MethodInner{}
}
}
As an anonymous class declaration in a new expression. The expression could appear in a variety of contexts. For example:
package goo;
public class Tar {
public void test() {
Runnable r = new Runnable() {
public run() { }
};
}
}
This may be what you are looking for:
public class TopLevel {
public static void main(String[] args) {
TopLevel topLevel = new TopLevel();
Nested nested = new TopLevel.Nested();
Inner inner = topLevel.new Inner();
}
public static class Nested {
}
public class Inner {
}
}

Nested Interafce in java

This is my java code:
class A {
interface That {
void show();
}
}
class B implements A.That {
public void show() {
System.out.println("Hi");
}
}
public class MainClass {
public static void main(String args[]) {
A obj = new A();
obj.That object = new B();
object.show();
}
}
Since A is a class (not abstract) we can create its instance and than we can use members of that instance. Now interface is member so obj.That should work but javac says that obj.That is not package. Why?
Interfaces are always static when nested in a class. You should therefore access your interface declaration as A.That, not obj.That.

Anonymous Inner Class Working?

As I have gone through some of the programming sites which explains anonymous inner class in java.
But, I still have doubts that how it really works and on the conclusions which I made below.
Here is code :
public class Implementing {
public static void main(String[] args) {
SuperClass a = new SuperClass() { // ... 1st
public void call () { // ... 2nd
System.out.println("Method call");
}
public void call2 () { // creating new method in anonymous inner class
System.out.println ("New call2 Method in Anonymous Class");
}
};
a.call(); // ... 3rd
try {
a.getClass().getMethod("call2",null).invoke(a,null); // ... 4th
} catch (Exeception e) {
System.out.println(e);
}
}
}
class SuperClass {
public void call() {
System.out.println("Super Class");
}
}
What I understand is this :
At 1st :-
Anonymous inner class is sub-class.
we are creating instance of anonymous inner class as well as we
are extending the class SuperClass.
we are running constructor of SuperClass, but we created object
of anonymous class of type SuperClass.
polymorphism at work.
Actually, we are doing this at 1st :
* 1. anonymousClass extends SuperClass
* 2. anonymousClass a = new SuperClass()
* 3. { }; // our anonymous class field
At 2nd : - overrides SuperClass call Method().
At 3rd : - calling call() Method by object 'a'.
At 4th : - accessing new method call2() Method in anonymous inner class.
So, my these conclusions are right or wrong ? If wrong why they are wrong ? Please Explain.
Your code creating an Anonymous Class:
public static void main(String[] args) {
SuperClass a = new SuperClass() { // ... 1st
public void call() {
System.out.println("Method call");
}
public void call2() {
System.out.println("New call2 Method in Anonymous Class");
}
};
...
}
is the same as this code creating a Local Class:
public static void main(String[] args) {
class LocalClass extends SuperClass {
public void call() {
System.out.println("Method call");
}
public void call2() {
System.out.println("New call2 Method in Anonymous Class");
}
}
SuperClass b = new LocalClass();
...
}
except that the class is unnamed, aka anonymous.
Since you're doing this from a static method, and you're not using any local variables, they are both the same as this Static Nested Class:
static class NestedClass extends SuperClass {
public void call() {
System.out.println("Method call");
}
public void call2() {
System.out.println("New call2 Method in Anonymous Class");
}
}
If you look at the compiled .class files, you'll see they are all just classes:
SuperClass.class <-- Your superclass
Implementing.class <-- Your main class
Implementing$1.class <-- Anonymous class
Implementing$1LocalClass.class <-- Local class
Implementing$NestedClass.class <-- Nested class

Categories

Resources