Looking for java Keywords? Try Ask4Keywords

Java Language Неправильное использование API Reflection для изменения частных и конечных переменных


пример

Отражение полезно, когда оно правильно используется для правильной цели. Используя отражение, вы можете получить доступ к закрытым переменным и повторно инициализировать конечные переменные.

Ниже приведен фрагмент кода, который не рекомендуется.

import java.lang.reflect.*;

public class ReflectionDemo{
    public static void main(String args[]){
        try{
            Field[] fields = A.class.getDeclaredFields();
            A a = new A();
            for ( Field field:fields ) {
                if(field.getName().equalsIgnoreCase("name")){
                    field.setAccessible(true);
                    field.set(a, "StackOverFlow");
                    System.out.println("A.name="+field.get(a));
                }
                if(field.getName().equalsIgnoreCase("age")){
                    field.set(a, 20);
                    System.out.println("A.age="+field.get(a));
                }
                if(field.getName().equalsIgnoreCase("rep")){
                    field.setAccessible(true);
                    field.set(a,"New Reputation");
                    System.out.println("A.rep="+field.get(a));
                }
                if(field.getName().equalsIgnoreCase("count")){
                    field.set(a,25);
                    System.out.println("A.count="+field.get(a));
                }
            }                
        }catch(Exception err){
            err.printStackTrace();
        }
    }
}

class A {
    private String name;
    public int age;
    public final String rep;
    public static int count=0;
    
    public A(){
        name = "Unset";
        age = 0;
        rep = "Reputation";
        count++;
    }
}

Выход:

A.name=StackOverFlow
A.age=20
A.rep=New Reputation
A.count=25

Объяснение:

В обычном сценарии private переменные не могут быть доступны за пределами объявленного класса (без методов getter и setter). final переменные не могут быть повторно назначены после инициализации.

Reflection разрывов обоих барьеров можно злоупотреблять, чтобы изменить как частные, так и конечные переменные, как описано выше.

field.setAccessible(true) - ключ к достижению желаемой функциональности.