编辑引用的类

时间:2014-09-02 13:31:32

标签: java oop maven inheritance

我正在使用Maven项目。在引用的JAR中有一个包,它包含一个类文件。我需要在这个类中添加一些代码行,但不幸的是这个类不可编辑 我的想法是创建一个新类,从这个引用的类扩展它,并将我的代码行添加到新创建的类中。这里的问题是,代码有点复杂,类也相互扩展。

// existing class
public class ReferencedClass extends AnotherClass{
  // ...
}
// my idea
public class MyClass extends ReferencedClass{
  // add my code here
}

// where those classes are needed
public class SomeClass{
  anObject o = new anObject(); // creates new object, whose class also extends from ReferencedClass
}
// this class also extends from ReferencedClass
public class anObject extends ReferencedClass{
  // ...
}

我不确定,如何实例化我自己创建的类MyClass。我是否应该在所有类别中使用ReferencedClass? 我的问题是否有另一种解决方案,而根本没有创建新类?

谢谢!

1 个答案:

答案 0 :(得分:0)

如果要修改没有setter的字段,则包装器无用。下一个解决方案是否有用取决于您尝试修改的字段是private还是protected。如果访问修饰符是私有的,则只有类本身的实例才能修改该字段。如果受保护,子类也可以访问和修改该字段。

//this is our class within the library. We cant edit its source
class APIClass {
    private int privatefield;
    protected int protectedfield;

    public String doStuff() { ... }
    public int doMoreStuff() { ... }
}

class MyExtendedAPIClass extends APIClass {
    // you dont have to override doStuff and doMoreStuff

    void setValues() {
        protectedfield = 10; //compiles, protectedfield is protected
        privatefield = 1; //does not compile, privatefield is private
    }
}

如果它是private字段,并且您仍想更改其值,则可以使用反射(在这种情况下,您不需要其他类):

void setFieldWithReflection() {
    APIClass apiClass = new APIClass();
    try {
        Field fieldToEdit = apiClass.getClass().getField("privatefield");
        fieldToEdit.set(apiClass, 25);
    }
    catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
        e.printStackTrace();
    }
}

编辑:由于setter只设置了一个字段,你可以使用反射设置该字段。但是OP要求它是一种方法(我没有得到,但是没问题),我会采用这种方式:

//this is our class within the library. We cant edit its source
class APIClass {
    private int privatefield;

    public int getPrivatefield() {
        return privatefield;
    }
}

class MyExtendedAPIClass extends APIClass {
    // you dont have to override doStuff and doMoreStuff

    public void setPrivatefield(int value) {
        try {
            Field field = this.getClass().getSuperclass().getDeclaredField("privatefield");
            field.setAccessible(true);
            field.set(this, value);
        }
        catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

以上作品。用代码测试

MyExtendedAPIClass mApi = new MyExtendedAPIClass();
mApi.setPrivatefield(5);
System.out.println(mApi.getPrivatefield);//outputs '5'