Есть ли способ в java или scala, который позволяет автоматически переопределять методы суперкласса?
Отказ от ответственности: я не претендую на опытного программиста, пожалуйста, не убивайтеЯ для любых злодеяний кодирования ниже.
У меня есть оболочка B класса A, которая делает некоторые вещи и делегирует два разных экземпляра A. Проблема в том, что класс A имеет очень большое количество методов.Вот моя оригинальная реализация Java .Это монстр с огромным дублированием кода.Это работает, но, вероятно, содержит много ошибок, некоторые из которых, возможно, трудно отследить, некоторые из них просто будут давать неправильные результаты без примечания.
Вот моя первая попытка повторной реализации с использованием структурной типизации scala .
def get(key: Array[Byte]): Array[Byte] = {
val f: (Transaction) => Response[Array[Byte]] = _.get(key)
wrap[Array[Byte]](f, redundancySwitch, currentDB, key).get()
}
остальное оставлено для общей функции переноса.Это уже приятно!Но мне все еще нужно реализовать каждый метод индивидуально и конкретно.
Моей следующей мыслью было попытаться создать единую (отражающую) обобщенную реализацию для копирования в каждое тело переопределяющего метода, чтобы в определении объекта функции f было что-то, что могло бы заполнить имя текущегоВызов метода.
def get(key: Array[Byte]): Array[Byte] = {
val f: (Transaction) => Response[Array[Byte]] = _.someReflectionMagic.nameOfCurrentlyCallingMethod(args)
Получение объекта метода - это нормально, но не то, как передать его в f, и, похоже, нет способа получить и скопировать аргументы вызываемого в данный момент метода.Вот моя попытка боли:
def zadd(key: String, score: Int, value: String) = {
// get the current Method
val thisMethod = new Object().getClass.getEnclosingMethod
val paramTypes = thisMethod.getParameterTypes
val returnType = thisMethod.getReturnType;
// this doesn't exist. how to reflectively forward parameter values (not parameter Types) into an Array for later reflective method invocation?
val params = thisMethod.getParameters
// I want to avoid to get it manually:
val params = new Array[Object]
params(0) = key
params(1) = score
params(2) = value
// this doesn't work. how to indicate the returnType here?
def f(t: Transaction): Response[returnType.class] =
t.getClass.getMethod(thisMethod.getName, paramTypes).
invoke(t,params).
asInstanceOf(Response[String])
wrap[String](f, redundancySwitch, currentDB, key).get()
}
private def getMethodName: String = {
val ste: Array[StackTraceElement] = Thread.currentThread.getStackTrace
return ste(2).getMethodName
}
это выглядит ужасно и, вероятно, действительно ужасно.Вы эксперты, есть ли что-нибудь, что могло бы заставить это работать?Надеюсь, по крайней мере, цель ясна?
Этот подход все еще требует наличия> 200 тел методов в моем классе-обертке.Интересно, есть ли какой-нибудь способ полностью обойтись без этого: класс A, обертывающий класс B, который выглядит снаружи, как будто B имеет все методы A, даже явно не реализуя их.Когда B вызывается методом A x (args: T): U, автоматическое переопределение / автоматическое делегирование для одного обобщенного метода By (x: T => U).y () будет что-то вроде метода wrap () во второй ссылке.Однако многие из вышеперечисленных проблем остаются ... то есть, как захватить аргументы и применить имя метода к структурному типизированному значению ...
имеет ли это смысл?Это не представляется возможным с помощью отражения Java / Java.Есть ли в скале что-нибудь, что могло бы мне помочь?Может быть, какое-нибудь экспериментальное отражение в скале?
Большое спасибо за любые подсказки