简体   繁体   中英

Access private object instance attribute in class using java reflection

I want to access the car object instance in the Test class from another class

class Test {

private car = new car(12);

}

class car {

     int i;

  car(int i) {
      this.i = i;
  }

}

Seeing your codes has errors (eg class car must be Car ), I would suggest reading tutorials such as this one and this one , on how to retrieve fields using reflection.

Here's a quick example based on your comment:

public class Test{

private car = new car(12); 

    public Test() {
        Fields[] fields = this.getClass().getDeclaredFields();
        if (fields != null) {
            for (Field field: fields) {
                Class<?> fieldType = field.getType();
                System.out.println(fieldType.getName());

                if (Car.class == fieldType) {
                    System.out.println("Field: " + field.getName() + " is of type " + Car.class.getName());
                }
            }
        }
    }
}

To access a private attribute of a class you need to make a method to return that attribute / field. so to return the car of Test write public Car getCar(){ return car; }

I wanted to do this to inspect some classes and find their default internal state after the new operator. Anyway I found the answer on this tutorial:

The whole tutorial series is useful. If you are in a hurry, I've pasted the interesting bit here:

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

 Field privateStringField = PrivateObject.class.
             getDeclaredField("privateString");

 privateStringField.setAccessible(true);

 String fieldValue = (String) privateStringField.get(privateObject);
 System.out.println("fieldValue = " + fieldValue);

Simple really. Once you find someone with time to explain. Thank goodness for stackoverflow.

For tests that really must access private members, see if you can set the private members to protected, and then have the Test (or a testing wrapper) subclass the "to be tested" object. That said, it's better to test 100% through method calls.

Testing is supposed to allow for encapsulation, so you really want to get out of the business of looking at an object's internals. If you break encapsulation in your testing framework, you lose all of the possible maintainability benefits of having encapsulation. In plain words, if you ever try to "fix" your object, you'll have to rewrite all of your tests to comply with the new "fixed" architecture.

It is far, far better to just test the part of the Object that the rest of the world will see, which is the outside after you've read / set / processed whatever is required. That way, if you ever change the internal guts, you will have a suite of tests already "ready to go" to verify your changes didn't break the object's behavior as viewed from the rest of the world.

Test test = new Test();
Field f = test.getClass().getField("car");
Object car = f.get(test);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM