Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Создание адаптера для java класса


Автор: Dude03 29.4.2008, 18:49
Вот у меня есть два таких класса. Пример утрированный специально=)

Код

public class A {
    int a;

    public int getA() {
        return a;
    }
    
    public void setA(int a) {
        this.a = a;
    }
}

public class B {
    int a;

    public int getA() {
        return a;
    }
    
    public void setA(int a) {
        this.a = a;
    }
}

public C {
   public static void process(A a) {
      a.setA(1);
   }
}


Хочеться получить автоматом в runtime вот это:
Код

public class D extends A {
    private B b;

    public int getA() {
        return b.getA();
    }
    
    public void setA(int a) {
        this.b.setA(a);
    }
}

То есть чтобы это все нормально работало в методом C.process ...
Или получить тот же эффект другим способом.
Название поле и в А, и в В совершенно одинаковые и названия методов следуют javabean соглашению.

ЗЫ. почему-то я уверен, что есть готовое решение=).


Автор: ivg 29.4.2008, 20:38
Класс D нужно сгенерировать в runtime? А зачем? Слишком много классов типа A и B для которых нужно это сделать? Если так тогда http://java.sun.com/javase/6/docs/api/java/lang/reflect/Proxy.html может помочь.
Если нет, добавьте в класс D конструктор, который будет принимать объект класса B и соответственно вызывайте
Код

B b = .....
C.process(new D(b));

Автор: Dude03 29.4.2008, 22:06
Да, классов достаточно. Не хочется мараться. Механизм proxy из jdk работают только при реализации классом некоторого интерфейса. 

Нашел класс Enchancer из cglib и для него можно написать interceptor. Все будет тип-топ.
Но писать не хочется. Не в том смысле, что мне лень(тем более что я уже написал ;-) ) , а в том, что не хочется включать новые классы в проект. Вот...

Код

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;


class A {
    int a;
    public int getA() {
        return a;
    }
    
    public void setA(int a) {
        this.a = a;
    }
}

class B {
    int b;
    public int getA() {
        return b;
    }
    
    public void setA(int a) {
        this.b = a;
    }
}

class C {
    public static void process(A a) {
        a.setA(1);
    }
}


class I implements MethodInterceptor {

    private Object o;
    private Class realClass;
    
    public I(Object o, Class clazz) {
        this.o = o;
        realClass = clazz;
    }
    
    public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
        return realClass.getMethod(arg1.getName(), arg1.getParameterTypes()).invoke(o, arg2);
    }

}

public class Main   {

    public static void main(String[] args) throws Exception {
        B b = new B();
        b.setA(2);
        I interceptor = new I(b, B.class);
        Enhancer e = new Enhancer();
        e.setSuperclass(A.class);
        e.setCallback(interceptor);
        Object bean = e.create();
        C.process((A) bean);
        System.out.println(b.getA());
    }
    
}



Может кто-нить может предложить лучшую реализацию? очень надо=)

Автор: w1nd 3.5.2008, 04:18
Если вам нужно извлечь из любого класса, невзирая на его тип, определённое свойство - рефлексия вас спасёт.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)