Calling newly defined method from anonymous class
Asked Answered
A

6

22

I instantiated an object of an anonymous class to which I added a new method.

Date date = new Date() {
    public void someMethod() {}
}

I am wondering if it is possible to call this method from outside somehow similar to:

date.someMethod();
Authentic answered 20/3, 2013 at 15:16 Comment(7)
Why don't you try it and see if it compiles & runs?Frady
Why use an anonymous class -- what's your motivation for this? In fact this is a situation where it is best to not use anonymous classes.Samsara
You could probably do it with reflection, but you probably dont want to...Gambado
The last line does not compile. I wondered if it is possible to call this method in a manner similar to last line.Authentic
@HovercraftFullOfEels So the best place to use an anonymous class is when I just override or implement methods of parent classes and interfaces respectively?Indecent
Note that var (Java 10) actually allows this. Although this is one of the var-tricks that probably should not be used in production.Sheatfish
@HovercraftFullOfEels obviously as an active inquisitor learning all tricks and traps of javaFlea
A
34

Good question. Answer is No. You cannot directly call date.someMethod();
Let's understand first what is this.

Date date = new Date()  { ... }; 

Above is anonymous(have no name) sub-class which is extending Date class.

When you see the code like,

    Runnable r = new Runnable() {

        public void run() {

        }

    };

It means you have defined anonymous(have no name) class which is implementing(not extending) Runnable interface.

So when you call date.someMethod() it won't be able to call because someMethod is not defined in superclass. In above case superclass is Date class. It follows simple overriding rules.

But still if you want to call someMethod then following is the step.

Fisrt way>
With reference variable 'date'
date.getClass().getMethod("someMethod").invoke(date);

Second way>
With newly created anonymous sub-class of Date class's object.

new Date() 
{
    public void someMethod() {
          System.out.println("Hello");
    }
}.someMethod();   //this should be without reference 'date'
Antalya answered 20/3, 2013 at 16:22 Comment(1)
So, I posted a similar question at #58671956 My question is regardless of the fact that whether the supertype(class or interface ) has declared that method or not, anonymous class should be able to define its own method as written in the Oracle Java SE tutorial of. Please refer the link I've shared in my original question.Marquet
P
10

Basically no.

This uglyness can do it however...

Date date = new Date() {
  public Date someMethod() { 
     //do some stuff here
     return this;
  }
}.someMethod();

But aside from this, you will only be able to call that method (which does not exist in the parent class) using reflection only, like this:

date.getClass().getMethod("someMethod").invoke(date);

(try-catch left out for sake of clarity...)

But seriously, don't do this! I'd feel being hated by the person who wrote this code, if I stumbled upon this in a codebase I have to work on.

Policyholder answered 20/3, 2013 at 15:20 Comment(0)
B
8

Without using reflection you can't: the method is not part of the Date API and date is only a date as far as the compiler is concerned.

The only way you can use someMethod is by calling it on the newly created instance directly:

new Date() { public void someMethod() { } }.someMethod();
Brabant answered 20/3, 2013 at 15:19 Comment(4)
Huh, I was not aware you could call a non-API method on creation. I wonder what the purpose is for that?Alexia
@iamnotmaynard There might not be a purpose. It's just that the type of an anonymous inner class expression is that inner class, not its named parent. So it's more of a case of the compiler not preventing you from calling public methods of an AIC even if they'll never be accessible anywhere else.Trampoline
I have never used it to be honest but it makes sense from a compiler's perspective.Brabant
@assylias, This is not the only solution. It is possible with reflection too, as demonstrated by Ppeterka's and AmitG's answers.Checkerberry
N
8

In Java 10+, use var keyword

var date = new Date() {
    public void someMethod() { }
};

date.someMethod();
Nilgai answered 11/7, 2019 at 2:20 Comment(0)
O
2

No, that is what method-local classes are for.

 class MyDate extends Date() {
   public void someMethod() {...}
 }
 MyDate date = new MyDate();
 date.someMethod();
Olympie answered 20/3, 2013 at 15:21 Comment(0)
T
1

I don't know why you would do this, but as written it is not possible, because Date does not declare someMethod.

However you can declare a local class inside the method, e.g:

void foo ( )
{
  class MyDate extends Date
  {
     public void someMethod( );
  }

  MyDate date = new MyDate( );

  date.someMethod( );
}

Once again, I would suggest using a normal class first, because local classes, by their nature, cannot be tested.

Tagalog answered 20/3, 2013 at 15:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.