Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set Value of Private Static Field

I want to set the value of a private field using reflection for unit testing.

Problem is, that field is static.

Here's what I'm working from:

/**    * Use to set the value of a field you don't have access to, using reflection, for unit testing.    *     * Returns true/false for success/failure.    *     * @param p_instance an object to set a private field on    * @param p_fieldName the name of the field to set    * @param p_fieldValue the value to set the field to    * @return true/false for success/failure    */   public static boolean setPrivateField(final Object p_instance, final String p_fieldName, final Object p_fieldValue) {     if (null == p_instance)       throw new NullPointerException("p_instance can't be null!");     if (null == p_fieldName)       throw new NullPointerException("p_fieldName can't be null!");      boolean result = true;      Class<?> klass = p_instance.getClass();      Field field = null;     try {       field = klass.getDeclaredField(p_fieldName);        field.setAccessible(true);       field.set(p_instance, p_fieldValue);      } catch (SecurityException e) {       result = false;     } catch (NoSuchFieldException e) {       result = false;     } catch (IllegalArgumentException e) {       result = false;     } catch (IllegalAccessException e) {       result = false;     }      return result;   } 

I realize this has probably already been answered on SO, but my search didn't turn it up...

like image 846
Tom Tresansky Avatar asked Jul 13 '10 16:07

Tom Tresansky


People also ask

How do you set a private static field value in Java?

So: field. set(null, p_fieldValue); This will let you set the static field.

How do you inject a value to a static field?

Solution First, PropertyController, which is a RestController, is being initialized by Spring. Afterward, Spring searches for the Value annotated fields and methods. Spring uses dependency injection to populate the specific value when it finds the @Value annotation.

Can you have a private static variable?

Just like an instance variables can be private or public, static variables can also be private or public.

How do I change the value of the final static variable in Java?

In Java, non-static final variables can be assigned a value either in constructor or with the declaration. But, static final variables cannot be assigned value in constructor; they must be assigned a value with their declaration.


2 Answers

Basically the problem is your utility method, which assumes you have an instance. It's reasonably easy to set a private static field - it's exactly the same procedure as for an instance field, except you specify null as the instance. Unfortunately your utility method uses the instance to get the class, and requires it to be non-null...

I'd echo Tom's caveat: don't do that. If this is a class you have under your control, I'd create a package level method:

void setFooForTesting(Bar newValue) {     foo = newValue; } 

However, here's a complete sample if you really, really want to set it with reflection:

import java.lang.reflect.*;  class FieldContainer {     private static String woot;      public static void showWoot()     {         System.out.println(woot);     } }  public class Test {     // Declared to throw Exception just for the sake of brevity here     public static void main(String[] args) throws Exception     {         Field field = FieldContainer.class.getDeclaredField("woot");         field.setAccessible(true);         field.set(null, "New value");         FieldContainer.showWoot();     } } 
like image 85
Jon Skeet Avatar answered Oct 02 '22 13:10

Jon Skeet


Just pass null for the object-instance argument. So:

field.set(null, p_fieldValue); 

This will let you set the static field.

like image 34
Vivin Paliath Avatar answered Oct 02 '22 15:10

Vivin Paliath