在java中访问问题

时间:2009-12-07 17:59:32

标签: java delegation

我正在使用第三方框架,结果我需要将其一些对象包装为我的一个类的委托。

class Foo { // 3rd party class.
    protected void method() {}
}

class FooWrapper extends Foo {
    private Foo mDelegate;

    public FooWrapper(Foo inDelegate) {
        mDelegate = inDelegate;
    }

    protected void method() {
        mDelegate.method(); // error can't access protected method() of mDelegate
    }
}

所以有问题。我需要将此方法委托给内部对象,但它受保护,因此无法访问。

有关解决此特定问题的方法的任何想法?这适用于Java 1.3。

4 个答案:

答案 0 :(得分:3)

为什么要构建一个单独的Foo实例? FooWrapper已经是Foo。

class Foo {
    protected void method() {}
}

class FooWrapper extends Foo {

    protected void method() {
        super.method();
    }
}

编辑:如果你真的必须有单独的实例,一种方法(尽管有点丑陋)是使用反射:

public class Foo {

    protected void method() {
        System.out.println("In Foo.method()");
    }
}

public class FooWrapper extends Foo {

    private Foo foo;

    public FooWrapper(Foo foo) {
        this.foo = foo;
    }

    public void method() {
        try {
            Method m = foo.getClass().getDeclaredMethod("method", null);
            m.setAccessible(true);
            m.invoke(foo, null);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Edit2:根据您的评论,有两个Foo子类,一个只提供受保护方法的公共版本,另一个重写所有重要方法。第一个看起来和行为完全像一个Foo,第二个可以做你需要做的任何事情:

public class Foo {

    protected void method() {
        System.out.println("In Foo.method()");
    }
}

public class DelegateFoo extends Foo {

    public void method() {
        super.method();
    }
}

public class FooWrapper extends Foo {

    private DelegateFoo foo;

    public FooWrapper(DelegateFoo foo) {
        this.foo = foo;
    }

    public void method() {
        foo.method();
        /* extra logic here */
    }
}

答案 1 :(得分:2)

当我遇到这样的情况时,我做了什么,它不好,但是它有效,是在与Foo相同的包中创建一个PublicFoo(但是在你的源代码中),让它扩展Foo,并覆盖受保护的方法并将其公开。

现在,FooWrapper可以扩展PublicFoo并做任何你想做的事。

但是,请注意,如果原始jar已签名并已密封,则需要先删除签名,然后才能部署它。 (您可以进入jar中的Manifest目录,只需删除证书)

答案 2 :(得分:0)

好吧,如果它具有对其属性的公共访问权限(可以是getter或公共变量),则可以创建一个复制构造函数:

public FooWrapper(Foo inDelegate) {
    this.property1 = inDelegate.getProperty1();
    this.property2 = inDelegate.getProperty2();
    // for every property
}

如果属性是对象......很棒,甚至更好,因为当你通过原始对象访问时,你所做的任何更改都会显示出来! (也就是说,直到你替换其中一个对象,你必须使用像String这样的不可变类。)

答案 3 :(得分:-1)

超类的受保护方法的子类should have access

如果你只是调用super.method()而不是mDelegate.method(),它会去;你要包装父类实例化它。