1

Suppose we have a hierarchy like this:

class Parent {
  public static final String BASE_NAME = "parent";
  public static final String X_URL = BASE_NAME + "/x";
  public static final String Y_URL = BASE_NAME + "/y";
}

class ChildA extends Parent {
  public static final String BASE_NAME = "childA";
  public static final String X_URL = BASE_NAME + "/x";
  public static final String Y_URL = BASE_NAME + "/y";

  @RequestMapping(value= X_URL)
  public String renderXPage(){...}
}

as you can see the X_URL and Y_URL are repeating both in parent and child, if the child can feed in its own BASE_NAME to the parent, we can eliminate redundant repetition of those constants and then we can use them for the annotation value. How to do this in Java ?

Mehdi
  • 3,795
  • 3
  • 36
  • 65
  • 7
    If it were to be possible, then it would violate static final modifiers. Hence not possible. – pvpkiran Jan 03 '19 at 09:43
  • @pvpkiran maybe there is a hack for that ;-) – Mehdi Jan 03 '19 at 09:45
  • In Parent , `public static final String X_URL = ChildA.BASE_NAME + "/x"` ? You want to do this? – Ken Chan Jan 03 '19 at 09:48
  • @KenChan no because we have more than 1 child – Mehdi Jan 03 '19 at 09:56
  • All possible hacks, such as those involving reflection, are extremely fragile and not guaranteed to work except in very specific situations, see https://stackoverflow.com/questions/53395929/is-there-a-limit-to-overriding-final-static-field-with-reflection/53396830#53396830 - don't try this at home, as this question demonstrates, it can suddenly start failing at a whim of the JIT – Hulk Jan 03 '19 at 09:57
  • 2
    @Hulk `final` `static` fields may be treated as constants by compiler, so it can be inlined at class loading time. Which mean that even if you change it using some hack it may be already inside annotation. – talex Jan 03 '19 at 10:02
  • 2
    @talex yes, exactly. In the question I linked to, seemingly working reflection code broke after a while when the JIT kicked in and made use of the permission to inline a constant - you can never be sure such code will work reliably, even if it passes several tests. – Hulk Jan 03 '19 at 10:04
  • @Hulk is there any other possible solution, I mean not the final constants, these constants are repeating all over my codes and I am frustrated, I would like to find a way to reuse them and assign them to my annotations – Mehdi Jan 03 '19 at 10:06
  • @Hulk of course I know that. But this way you can't use them within your annotation – Mehdi Jan 03 '19 at 10:12

2 Answers2

5

There is no way to reliable achieve this.

You can have @RequestMapping annotation on class and put base part of URL there.

Example:

@RequestMapping("ChildA")
class ChildA {
  @RequestMapping(value= "x")
  public String renderXPage(){...}
}

renderXPage will handle "ChildA/x" URL.

talex
  • 17,973
  • 3
  • 29
  • 66
0

Using the solution of @talex I came up with this neat solution:

public interface CommonRelativeUrls {
  String X_URL = "/x";
  String Y_URL = "/y";
}

public interface Entities {
  String CLASS_A = "class-a";
  String CLASS_B = "class-b";
  ...
}

@RequestMapping(value = Entities.CLASS_A)
public class ClassA implements CommonRelativeUrls {
  @RequestMapping(value= X_URL)
  public String renderXPage(){...}
}
Mehdi
  • 3,795
  • 3
  • 36
  • 65