10

I saw some codes in slf4j as show below. I don't know why to avoid constant folding in here. Is it necessary to do that? or just best practice. what's the benefit of doing this?

Thanks.

/**
  * Declare the version of the SLF4J API this implementation is compiled against. 
  * The value of this field is usually modified with each release. 
  */
// to avoid constant folding by the compiler, this field must *not* be final
public static String REQUESTED_API_VERSION = "1.6";  // !final**
StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
easycoder
  • 305
  • 2
  • 3
  • 12
  • Have you looked at the wiki on this topic? I think it explains it pretty well. http://en.wikipedia.org/wiki/Constant_folding – CoolBeans Jan 15 '11 at 18:04
  • You can use a method instead of exposing this field (probably best), use `final` but pass the value through a method (`"1.6".toString()`) or add some code to prevent it being a *compile-time constant* yet not add any unnecessary bytecode (`null!=null?"": "1.6"`). – Tom Hawtin - tackline Jan 15 '11 at 18:11
  • Yeah, public static constants are icky! – Steven Schlansker Jan 15 '11 at 18:22
  • @CoolBeans, I have checked the wiki. The example in wiki is explaining what the constant folding is. I just confused at this point. Thanks for everyone explanation. It seems a best practice for library release. :) – easycoder Jan 15 '11 at 21:19
  • The code is bad and I'd bet it dates for years. It should have been a method call or something like that: `public static String REQUESTED_API_VERSION = new String("1."+"6"); //new String is not literal, so it'll result in GETSTATIC` – bestsss Jan 28 '11 at 11:54
  • to bestsss, the public static String REQUESTED_API_VERSION = new String("1."+"6"); is not a best practice. because it will generate a new string object unnecessary. should just keep "1.6" is fine. – easycoder Jan 29 '11 at 02:26
  • @easycoder, if you'd mean that 2 strings in the perm gen (w/ "6" most like there anyways), yeah you can keep 1.6 and it'd be fine; I left it to illustrate the idea. Normally I'd use "xxx".concat("") and it keeps the literal. Sometimes I'd prefer String not to be == to the literals. – bestsss Jan 29 '11 at 14:31

1 Answers1

6

In the particular case where you are releasing a library, you often don't have control of the final version of the logging library that is eventually linked in at the end. For example you are using version 1.6, and the application that is using your library might use 1.6.1 to get a bugfix. Since it's only a point release the API should be compatible, but if your library inspects the SLF4J version it should show 1.6.1 not 1.6.

If the constant is inlined you will see 1.6 (since it's copied into your class file) even if the library is upgraded after the fact.

Steven Schlansker
  • 37,580
  • 14
  • 81
  • 100
  • A project I used to work on, AviSynth, found this out the hard way when they went to extend their ABI between minor versions. Wasn't possible due to too much inlining and too much VC6 dependence. The next major version used a "virtual" ABI and worked great. – SilverbackNet Jan 15 '11 at 18:14