2016-02-01 6 views
-5

У меня есть класс, который представляет собой уровень в моей игре. Я пишу ИИ, который должен быть в состоянии предсказать, как мир будет реагировать шаг за шагом на свои действия. Эти пошаговые моделирования в настоящее время обрабатываются частными функциями, но я хотел бы, чтобы ИИ мог сделать копию экземпляра уровня и получить доступ к этим частным функциям на этой копии.Доступ к приватным методам в Java

Как это можно сделать?

+4

Почему они закрыты, если вам нужно публично открыть их? –

+0

Не знаете, к какому классу обращается какой-то, но если вам действительно нужно ... отражение может это сделать –

+0

@Dave Newton Я не хочу, чтобы другие классы могли изменять состояние игры непреднамеренными способами. – Rizhiy

ответ

2

Вы можете использовать отражение для этого. Например,

public class PrivateObject { 

    private String privateString = null; 

    public PrivateObject(String privateString) { 
    this.privateString = privateString; 
    } 

    private String getPrivateString(){ 
    return this.privateString; 
    } 
} 

Для этого класса,

PrivateObject privateObject = new PrivateObject("The Private Value"); 

Method privateStringMethod = PrivateObject.class.getDeclaredMethod("getPrivateString", null); 

privateStringMethod.setAccessible(true); 

String returnValue = (String) privateStringMethod.invoke(privateObject, null); 

System.out.println("returnValue = " + returnValue); 

Подробнее here.

+4

Ваш ответ правильный, но отражения не следует использовать для такого рода вещей. он должен быть зарезервирован для фреймворков или библиотеки низкого уровня. OP должен лучше моделировать объект состояния только для чтения и позволить его AI доступ к этому состоянию –

+0

Я искал больше шаблонов проектирования, а затем менял модификатор доступа. – Rizhiy

+0

@Rizhiy не думаю, что вы можете получить доступ к приватным методам, используя любые шаблоны проектирования. – Msp

3

Если не использовать отражение, вам необходимо увеличить видимость от частного до того, что доступно вне класса.

Рассмотрите возможность использования пакета частным - это на самом деле видимость по умолчанию модификатор, обозначенный не помещая никакого явного модификатора:

class Foo {  // A package private class. 
    int bar;  // A package private field. 
    void baz() {} // A package private method. 
} 

Таких методы будут видны только к классам в том же пакете - вы можете поместить свои классы AI в том же пакете.

Если вы не хотите, чтобы третьи стороны могли определять классы внутри одного и того же пакета, что дало бы им видимость этих методов, вы можете использовать что-то вроде sealed jar.

+0

К сожалению, из-за организационных причин мои классы должны быть в другом пакете. – Rizhiy

+0

@ Рижи хорошо, ваши методы должны быть публичными. Но невозможно остановить любой класс, называемый ими тогда. Такова модель упаковки java. –

+0

Я нашел компромисс, сделав его защищенным и распространив его на свой класс в моем пакете и переопределив метод там, а затем вызвав оригинал из расширения. – Rizhiy

0

Неотражающий ответ (потому что я не хотел вмешиваться в доступ во время выполнения): изменить модификатор доступа от частного к защищенному, расширить основной класс и создать новый метод с общедоступным модификатором, из которого может быть использован оригинальный метод называется.

Таким образом, реальный уровень все еще нельзя изменить ненадлежащим образом, и ИИ может использовать требуемые функции.

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