How to read the value of a private field from a different class in Java?

前端 未结 14 1706
梦毁少年i
梦毁少年i 2020-11-21 11:28

I have a poorly designed class in a 3rd-party JAR and I need to access one of its private fields. For example, why should I need to choose priv

相关标签:
14条回答
  • 2020-11-21 12:01

    One other option that hasn't been mentioned yet: use Groovy. Groovy allows you to access private instance variables as a side effect of the design of the language. Whether or not you have a getter for the field, you can just use

    def obj = new IWasDesignedPoorly()
    def hashTable = obj.getStuffIWant()
    
    0 讨论(0)
  • 2020-11-21 12:02

    You can use Manifold's @JailBreak for direct, type-safe Java reflection:

    @JailBreak Foo foo = new Foo();
    foo.stuffIWant = "123;
    
    public class Foo {
        private String stuffIWant;
    }
    

    @JailBreak unlocks the foo local variable in the compiler for direct access to all the members in Foo's hierarchy.

    Similarly you can use the jailbreak() extension method for one-off use:

    foo.jailbreak().stuffIWant = "123";
    

    Through the jailbreak() method you can access any member in Foo's hierarchy.

    In both cases the compiler resolves the field access for you type-safely, as if a public field, while Manifold generates efficient reflection code for you under the hood.

    Discover more about Manifold.

    0 讨论(0)
  • 2020-11-21 12:04

    Using the Reflection in Java you can access all the private/public fields and methods of one class to another .But as per the Oracle documentation in the section drawbacks they recommended that :

    "Since reflection allows code to perform operations that would be illegal in non-reflective code, such as accessing private fields and methods, the use of reflection can result in unexpected side-effects, which may render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform"

    here is following code snapts to demonstrate basic concepts of Reflection

    Reflection1.java

    public class Reflection1{
    
        private int i = 10;
    
        public void methoda()
        {
    
            System.out.println("method1");
        }
        public void methodb()
        {
    
            System.out.println("method2");
        }
        public void methodc()
        {
    
            System.out.println("method3");
        }
    
    }
    

    Reflection2.java

    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    
    public class Reflection2{
    
        public static void main(String ar[]) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
        {
            Method[] mthd = Reflection1.class.getMethods(); // for axis the methods 
    
            Field[] fld = Reflection1.class.getDeclaredFields();  // for axis the fields  
    
            // Loop for get all the methods in class
            for(Method mthd1:mthd)
            {
    
                System.out.println("method :"+mthd1.getName());
                System.out.println("parametes :"+mthd1.getReturnType());
            }
    
            // Loop for get all the Field in class
            for(Field fld1:fld)
            {
                fld1.setAccessible(true);
                System.out.println("field :"+fld1.getName());
                System.out.println("type :"+fld1.getType());
                System.out.println("value :"+fld1.getInt(new Reflaction1()));
            }
        }
    
    }
    

    Hope it will help.

    0 讨论(0)
  • 2020-11-21 12:05

    You need to do the following:

    private static Field getField(Class<?> cls, String fieldName) {
        for (Class<?> c = cls; c != null; c = c.getSuperclass()) {
            try {
                final Field field = c.getDeclaredField(fieldName);
                field.setAccessible(true);
                return field;
            } catch (final NoSuchFieldException e) {
                // Try parent
            } catch (Exception e) {
                throw new IllegalArgumentException(
                        "Cannot access field " + cls.getName() + "." + fieldName, e);
            }
        }
        throw new IllegalArgumentException(
                "Cannot find field " + cls.getName() + "." + fieldName);
    }
    
    0 讨论(0)
  • 2020-11-21 12:06

    Try FieldUtils from apache commons-lang3:

    FieldUtils.readField(object, fieldName, true);
    
    0 讨论(0)
  • 2020-11-21 12:06

    Just an additional note about reflection: I have observed in some special cases, when several classes with the same name exist in different packages, that reflection as used in the top answer may fail to pick the correct class from the object. So if you know what is the package.class of the object, then it's better to access its private field values as follows:

    org.deeplearning4j.nn.layers.BaseOutputLayer ll = (org.deeplearning4j.nn.layers.BaseOutputLayer) model.getLayer(0);
    Field f = Class.forName("org.deeplearning4j.nn.layers.BaseOutputLayer").getDeclaredField("solver");
    f.setAccessible(true);
    Solver s = (Solver) f.get(ll);
    

    (This is the example class that was not working for me)

    0 讨论(0)
提交回复
热议问题