1

Say I have private final static int N = 1 in class A

Is there any chance to 'hack' so that N becomes 2(without touching the source file A.java)?

The set pointcut seems not work on these final fields.

The thing is, I have the source code of some project, and I'm making some modifications to it to deploy it in our region. I'm trying to make these changes without touching the source file unless I have to.

@VinceEmigh reflection wouldn't work in my case. The source code looks like:

class MyClass
  private final static String[] NAMES = {"Name1", "Name2", "Name3"};

  public void createIsland() {
      //something
      int i = getNumberOfIsland();
      String name = NAMES[i];
      createIslandWithName(name);
      //something
  }
end

The thing is I need to change those hard coded NAMES to something else

kriegaex
  • 63,017
  • 15
  • 111
  • 202
Dean Winchester
  • 629
  • 5
  • 17
  • 2
    What would be the point of `final` fields if you were allowed to change values (for primitives, as in your case) or references? – TheLostMind Jul 22 '14 at 06:08
  • 3
    The first problem is that anything referring to that field will have the constant value baked into it, so changing the value of the field at execution time wouldn't affect that code. Fundamentally, this seems like a bad idea to me. What concrete problem are you trying to solve? I suspect you should take a step back and redesign. – Jon Skeet Jul 22 '14 at 06:09
  • Check this out, might be helpful: http://stackoverflow.com/questions/3301635/change-private-static-final-field-using-java-reflection – Vince Jul 22 '14 at 06:09

1 Answers1

4

Sample driver class:

package de.scrum_master.app;

public class Application {
    private final static String[] NAMES = { "Name1", "Name2", "Name3" };

    public static void main(String[] args) {
        for (String name : NAMES)
            System.out.println(name);
    }
}

Aspect:

package de.scrum_master.aspect;

import de.scrum_master.app.Application;

public aspect ConstantChanger {
    Object around() : get(* Application.NAMES) {
        System.out.println(thisJoinPointStaticPart);
        return new String[] { "Hack1", "Hack2", "Hack3", "Hack4", "Hack5" };
    }
}

Output:

get(String[] de.scrum_master.app.Application.NAMES)
Hack1
Hack2
Hack3
Hack4
Hack5

This way you change the array size as well as its content. Is that what you need?

kriegaex
  • 63,017
  • 15
  • 111
  • 202