2014-09-02 2 views
0

Я работаю с проектом 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?
Есть ли еще одно решение для моей проблемы, не создавая новый класс?

Спасибо!

+2

Если бы я был вами, я бы сделал класс обертки и использовал только этот класс в своем собственном проекте/коде. – stealthjong

+0

Трудно предоставить осмысленный совет, но если класс, который вы хотите изменить, не принадлежит вам, вы, вероятно, не должны его изменять. Нужно ли вам распространять один и тот же класс, трудно сказать, не зная, что вы действительно хотите с ним сделать. Альтернативы включают такие вещи, как АОП, простую композицию с делегацией, декораторы и т. Д. –

+0

@DaveNewton: Мне нужно только добавить короткий сеттер-метод. – user1170330

ответ

0

Если вы хотите изменить поле без сеттера, обертка не полезна. Независимо от того, полезно или нет следующее решение, зависит от того, будет ли поле, которое вы пытаетесь изменить, - 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(); 
    } 
} 

Edit: С сеттер просто устанавливает поле, вы можете просто установить это поле, используя отражение. Но 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' 
+0

Спасибо! Мне просто нужно добавить в класс другой метод setter, не изменяя никаких полей. – user1170330

+0

@ user1170330 См. Мое редактирование. Работает. – stealthjong

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