2016-05-28 2 views
1

У меня есть настройка на Eclipse Mars, где есть две зависимости. Оба являются одной и той же программой, но имеют разные версии. В этой программе есть класс InitialHandler. Конструктор этого класса изменился между двумя версиями программы с InitialHandler (ProxyServer, ListenerInfo) на InitialHandler (BungeeCord, ListenerInfo). BungeeCord - это подкласс ProxyServer.Java - принудительный вызов super() для использования конструктора из определенной зависимости

Я пытаюсь создать класс, совместимый как с новыми, так и с устаревшими версиями конструктора. Для этого мой класс также имеет два конструктора, которые принимают соответствующие параметры в качестве входных данных. Проблема заключается в том, что в конструкторе, который должен взять вход BungeeCord, вызов super() все еще использует конструктор из старой зависимости, который использует ProxyServer. See a screenshot here

Как заставить вызов super() использовать версию конструктора с параметром BungeeCord?

ответ

0

Я придумал решение, которое может работать в вашем сценарии, но она работает немного иначе, чем то, что вы изначально хотели решить (разрешающую из super вызовов):

public class OpenInitialHandler extends InitialServerLegacyDelegate { 

    public OpenInitialHandler(BungeeCord bungee, ListenerInfo listener) { 
     super(bungee, listener); 
    } 

    public OpenInitialHandler(ProxyServer proxyServer, ListenerInfo listener) { 
     super(proxyServer, listener); 
    } 
} 
public class InitialServerLegacyDelegate /* implements and extends whatever you need */ { 

    private static final Constructor<InitialDelegate> targetConstructor = InitialServer.getConstructors()[0]; 

    private final InitialServer delegate; 

    protected InitialServerLegacyDelegate(BungeeCord bungee, ListenerInfo listener) { 
     this(bungee, listener); 
    } 

    protected InitialServerLegacyDelegate(ProxyServer proxyServer, ListenerInfo listener) { 
     try { 
      // This is the critical part. 
      // Instead of binding/checking the constructor parameter types 
      // at compile-time, this will be resolved at runtime. 
      delegate = targetConstructor.newInstance(proxyServer, listener); 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 

    // implement all neccessary interface methods here 
    // and simply make them delegate methods 
} 

По существу, InitialServerLegacyDelegate обрабатывает это наследие. Похоже, действительный суперкласс (поскольку он реализует те же интерфейсы, как InitialServer, но в действительности это всего лишь делегаты всех вызовов к экземпляру InitialServer которые он решает во время выполнения

Одна из проблем, вы можете быть облицовкой:. Если ваш класс получает входной сигнал на OpenInitialHandler(ProxyServer proxyServer, ListenerInfo listener), где ProxyServer не типа BungeeCord. В этом случае, реализация потерпит неудачу с ClassCastException, если новая зависимость (с BungeeCord конструктора) присутствует и он получает не- BungeeCord -input.

Методы делегата могут быть легко созданы Eclipse. Более подробно см. this question on how to generate delegate methods in Eclipse.

Смежные вопросы