Java: метод вызывается с нулевым параметром, используя отражение в защищенном методе

#java #android

#java #Android

Вопрос:

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

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

Тестовая функция выглядит следующим образом:

 @Test
void updateMetrics() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    final BatteryMetric batteryMetric = new BatteryMetric(mockContext);
    final Method method = BatteryMetric.class.getDeclaredMethod("updateValues", Intent.class);
    final Intent intentValues = new Intent();

    intentValues.putExtra(BatteryManager.EXTRA_SCALE, 100);
    intentValues.putExtra(BatteryManager.EXTRA_TEMPERATURE, 30);
    intentValues.putExtra(BatteryManager.EXTRA_LEVEL, 50);
    intentValues.putExtra(BatteryManager.EXTRA_PLUGGED, 1);
    intentValues.putExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_GOOD);

    method.setAccessible(true);
    method.invoke(batteryMetric, intentValues);
    method.setAccessible(false);
}
 

И метод, который я вызываю, выглядит следующим образом:

 @Override
protected void updateValues(Intent intent) {
    final int maximumBattery = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
    final int temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0) / 10;
    final int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100 / maximumBattery;
    final int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
    final int health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_UNKNOWN);

    this.metrics.put(LABEL_TEMPERATURE, temperature);
    this.metrics.put(LABEL_PLUGGED, plugged);
    this.metrics.put(LABEL_HEALTH, health);
    this.metrics.put(LABEL_LEVEL, level);
}
 

Абстрактный класс, содержащий абстрактный метод, выглядит следующим образом:

 public abstract class BaseMetric {
    protected final Map<String, Integer> metrics = new HashMap<>();

    protected final Context context;

    protected BaseMetric(Context context) {
        this.context = context;
    }

    public abstract void start();

    public abstract void stop();

    protected abstract void updateValues(Intent intent);

    public Map<String, Integer> getMetrics() {
        return this.metrics;
    }
}
 

При игнорировании того, что отображает отладчик, все переменные в функции принимают значение 0 вместо значения по умолчанию. Почему это происходит и как это исправить?

Комментарии:

1. updateValues находится в BatteryMetric ? или в абстрактном классе?

2. @Eugene BatteryMetric расширяется из абстрактного класса, в котором находится абстрактный метод. Так что да.

3. Я вижу, что вы используете getDeclaredMethod , поэтому он BatteryMetric включен. method.setAccessible(true); в этом случае вам не нужно, и это не должно произойти. вам необходимо предоставить минимальный воспроизводимый пример.

4. @Eugene я добавил код абстрактного класса, чтобы сделать его более полным. но я не вижу, какой другой пример привести, если это буквально то, что я пытаюсь сделать

5. минимальный пример похож на репозиторий, который я могу импортировать и воспроизводить…