5

I have a constant class and I'm trying to set a batch number constant at run time with public static final String. My IDE is giving me a warning "static method declared final" and I'd like to know if I'm doing something incorrectly.

file gets value from Spring yml file.

private String file; (xxx-12345.txt)

public String getBatchNo() {
    return parseBatchNo(file);
}

public static final String parseBatchNo(String file) {
    return file.substring((file.lastIndexOf("-") + 1), (file.length() - 4));
}
Itamar Kerbel
  • 2,508
  • 1
  • 22
  • 29
codejunkie
  • 63
  • 6
  • 1
    Remove final keyword – Kevorkian Oct 03 '18 at 14:20
  • so if I call getBatchNo multiple times, it's not going to rerun the parseBatchNo logic? – codejunkie Oct 03 '18 at 14:26
  • Is your intention to run the logic of the `parseBatchNo` method only the first time it is called? Then you need to cache ("memoize") the result somewhere. – TiiJ7 Oct 03 '18 at 14:29
  • @George - *"so if I call getBatchNo multiple times, it's not going to rerun the parseBatchNo logic?"* No, like all methods, it will get run every time you call it. – T.J. Crowder Oct 03 '18 at 14:41
  • So if it's going to rerun the method with every call, what would the purpose be for using static final if I'm only every calling it from within the class. Why not switch it to private and just return a String? Also this might be a little off topic, but would someone be able to provide a cache example? – codejunkie Oct 03 '18 at 14:53
  • @George my answer provides a cache example (the value is cached in a static final field). – DodgyCodeException Oct 03 '18 at 14:58

3 Answers3

8

Static methods are not subject to overriding.

The final keyword hides the method. See the link in comments for more details.

Note that you should not rely on that behavior, although the language allows it. You should always invoke static methods as <class-name>.<method-name>.

  • 1
    See: https://stackoverflow.com/questions/1743715/behaviour-of-final-static-method – T.J. Crowder Oct 03 '18 at 14:22
  • @T.J.Crowder Good point, I was unaware of that. But shouldn't you always use the class name when invoking a static method? –  Oct 03 '18 at 14:39
  • Ah, we're getting into matters of style there. :-) (Yes, I would.) – T.J. Crowder Oct 03 '18 at 14:42
  • @alexrolea *shouldn't you always* does not mean that the language does *not* allow this - and thus, someone might abuse it; I would rephrase this answer as `final` and `static` *do* make sense, read my last comment under that answer, too – Eugene Oct 05 '18 at 09:50
  • @alexrolea it doesn’t matter what you should do when invoking a method. The key point is, the `final` modifier *does* make a difference regarding whether you can *declare* a method with the same signature in a subclass. – Holger Oct 05 '18 at 12:58
2

Static methods can not be overriden by extending class, hence the final keyword is useless in this case.

NiVeR
  • 9,644
  • 4
  • 30
  • 35
0

When applied to a method, the final keyword has a different meaning than when applied to a field: it does not mean "constant".

You can achieve what you want using some logic:

private static String batchNo;

public static String parseBatchNo(String file) {
    if (batchNo == null) {
        batchNo = file.substring((file.lastIndexOf("-") + 1), (file.length() - 4));
    }
    return batchNo;
}

(NB the above method is not thread-safe. It gets slightly more complicated if you need to call it from multiple threads.)

DodgyCodeException
  • 5,963
  • 3
  • 21
  • 42
  • You would need to remove the final from the class property as that value can't be set from the method and I believe as they said in other answers the final in the method is useless in this case. – codejunkie Oct 03 '18 at 15:38
  • @George you're right. I have corrected my mistake (caused by careless copy-and-paste) – DodgyCodeException Oct 03 '18 at 15:39