views:

45

answers:

2

I have a class, server. It has a private field f of type class fg. It in turn has a private field e of type int. I want to modify e, but I can't modify those classes. Succinctly stated, it's: server.(fg)f.(int).e

I tried this code, but I'm a bit rusty on my Java, let alone reflection. Line 4 throws a NullPointerException, because it looks like Line 3 isn't actually working like I expect.

Field fieldf = server.getClass().getDeclaredField("f");
fieldf.setAccessible(true);
Class classf = (Class) fieldf.get(server);
Field e = classf.getDeclaredField("e"); // Throws NullPointerException
e.setAccessible(true);
e.set(e, anumber);

Does anyone with more experience with reflection have any suggestions?

+1  A: 

I suspect it's more likely that server.f is currently null, so classf will be null. If you're convinced it isn't, please provide a short but complete program demonstrating the problem.

Jon Skeet
A: 

Here's how you would use reflection to implement server.f.e = someInt where f has type Foo and e has type int.

// (Warning - untested code ...)
Field fieldF = server.getClass().getDeclaredField("f");
fieldF.setAccessible(true);
Foo foo = (Foo) fieldF.get(server);
if (foo != null) {
    Field fieldE = Foo.class.getDeclaredField("e");
    fieldE.setAccessible(true);
    fieldE.set(foo, new Integer(someInt));
}

I'd just like to add that you should only be doing this kind of thing as a last resort:

  • You are breaking encapsulation of a couple of classes, and potentially doing things that might cause them to break horribly.
  • Your code is fragile. If someone changes the internal implementation details of either the Server or Foo classes, your code is liable to fail with runtime exceptions.
  • This is a very expensive way of setting a field.
Stephen C