Вызов нового метода из анонимного класса

Я создал объект анонимного класса, к которому добавил новый метод.

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

Мне интересно, если можно вызвать этот метод извне, как-то похоже на:

date.someMethod();

Ответ 1

Хороший вопрос. Ответ: Нет. Вы не можете напрямую позвонить date.someMethod();
Сначала давайте понять, что это такое.
Date date = new Date()  { ... }; 

Над анонимным (не имеют имени) подкласс, который расширяет класс Date.

Когда вы увидите код вроде,

    Runnable r = new Runnable() {

        public void run() {

        }

    };

Это означает, что вы определили анонимный (не имеющий имени) класс, который реализует (не расширяя) интерфейс Runnable.

Поэтому, когда вы вызываете date.someMethod(), он не сможет позвонить, потому что someMethod не, определенном в superclass. В вышеприведенном случае суперкласс - Date класс. Это следует за простыми правилами переопределения.

Но если вы хотите вызвать someMethod, то следующий шаг.

Способ Fisrt >
С ссылочной переменной 'Date'
date.getClass().getMethod("someMethod").invoke(date);

Второй способ >
С новым созданным анонимным подклассом объекта класса Date.

new Date() 
{
    public void someMethod() {
          System.out.println("Hello");
    }
}.someMethod();   //this should be without reference 'date'

Ответ 2

В принципе нет.

Эта уродство может сделать это, однако...

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

Но помимо этого вы сможете только вызвать этот метод (который не существует в родительском классе), используя только отражение:

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

(для большей ясности выбрана попытка улова)

Но серьезно, не делайте этого! Я чувствую, что меня ненавидит человек, который написал этот код, если я наткнулся на это в кодовой базе, над которой я должен работать.

Ответ 3

Без использования отражения вы не можете: этот метод не является частью API Date, а date - это только дата относительно компилятора.

Единственный способ, которым вы можете использовать someMethod, - это вызвать его непосредственно на вновь созданном экземпляре:

new Date() { public void someMethod() { } }.someMethod();

Ответ 4

Нет, для этого используются методы-локальные классы.

 class MyDate extends Date() {
   public void someMethod() {...}
 }
 MyDate date = new MyDate();
 date.someMethod();

Ответ 5

Я не знаю, почему вы это сделаете, но как написано, это невозможно, потому что Date не объявляет someMethod.

Однако вы можете объявить локальный класс внутри метода, например:

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

  MyDate date = new MyDate( );

  date.someMethod( );
}

Еще раз, я бы предложил сначала использовать класс normal, потому что локальные классы по своей природе не могут быть протестированы.

Ответ 6

В Java 10+ используйте ключевое слово var

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

date.someMethod();