Is there any way to modify the value of the “private static final” field in Java?

I know it's usually stupid, but don't shoot me before reading this question I promise I have a good reason to do this:)

Reflection can be used to modify regular private fields in Java, but Java will throw a security exception when trying to do the same for the final field

I would think it was strictly enforced, but I would ask, anyway, just in case someone came up with a hacker to do so

Let's say I have an external library and class "someclass"

public class SomeClass 
{
  private static final SomeClass INSTANCE = new SomeClass()

  public static SomeClass getInstance(){ 
      return INSTANCE; 
  }

  public Object doSomething(){
    // Do some stuff here 
  }
}

I wanted monkey patch someclass so that I could execute my own version of dosomething () Since there is no way (as far as I know) to really do this in Java, my only solution is to change the value of instance, so it returns my version of the class and modified methods

In essence, I just want to call the security parcel and call the original method.

External libraries always use getInstance () to get an instance of this class (that is, it is a singleton)

Edit: just to clarify, getInstance () is called by an external library, not my code, so just subclassing won't solve the problem

If I can't do this, the only other solution I can think of is to copy and paste the entire class and modify the method This is not ideal because I have to keep my fork up to date with library changes If someone has more maintainability, I can accept the suggestion

Solution

It's possible I've used this to stop the naughty threadlocals of unloading classes in webapps If you only need to use reflection to delete the final modifier, you can modify this field

Such a thing will do this:

private void killThreadLocal(String klazzName,String fieldName) {
    Field field = Class.forName(klazzName).getDeclaredField(fieldName);
    field.setAccessible(true);  
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    int modifiers = modifiersField.getInt(field);
    modifiers &= ~Modifier.FINAL;
    modifiersField.setInt(field,modifiers);
    field.set(null,null);
}

Some caches also have field #set, so some code may not run normally before running

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>