Calling newly defined method from anonymous class

前端 未结 6 1864
南笙
南笙 2020-12-01 16:26

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

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

I

相关标签:
6条回答
  • 2020-12-01 16:41

    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.

    0 讨论(0)
  • 2020-12-01 16:41

    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();
    
    0 讨论(0)
  • 2020-12-01 16:41

    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.

    0 讨论(0)
  • 2020-12-01 16:42

    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'
    
    0 讨论(0)
  • 2020-12-01 16:44

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

     class MyDate extends Date() {
       public void someMethod() {...}
     }
     MyDate date = new MyDate();
     date.someMethod();
    
    0 讨论(0)
  • 2020-12-01 16:53

    In Java 10+, use var keyword

    var date = new Date() {
        public void someMethod() { }
    };
    
    date.someMethod();
    
    0 讨论(0)
提交回复
热议问题