Legitimate use for a static initializer?

I remember a couple of years ago I used static initializers to invoke class-level setup operations. I remember that it was a very strange behavior, and I just decided to get away from them. Perhaps this was due to the fact that I ruined the top order or was a newbie. But I am faced with the need to review them, and I want to make sure that there is no better way that will be as brief.

I know this is not trendy, but I often have data-based classes that support a static list of instances imported from the database.

public class StratBand { private static volatile ImmutableList<StratBand> stratBands = importFromDb(); private final int minRange; private final int maxRange; private static ImmutableList<StratBand> importFromDb() { //construct list from database here } //constructors, methods, etc } 

When I have dozens of table-driven classes like this, this template is very concise (yes, I know that it is closely related to the class with a single data / instance source).

However, when I discovered the goodness of Google Guava, I want to use EventBus to update the static list when sending a specific event. I would create a static final boolean to call the static method that initialized the registration.

 public class StratBand { private static volatile ImmutableList<StratBand> stratBands = importFromDb(); private static final boolean subscribed = subscribe(); private final int minRange; private final int maxRange; private static ImmutableList<StratBand> importFromDb() { //construct list from database here } //constructors, methods, etc private static boolean subscribe() { MyEventBus.get().register(new Object() { @Subscribe public void refresh(ParameterRefreshEvent e) { stratBands = importFromDb(); } }); return true; } } 

This was very annoying because the compiler issued warnings on a subscription that was never used. In addition, he just added a mess. Therefore, I wonder if it is not kosher to use a static initializer, and there really is no better way if I do not separate it from two or more classes. Thoughts?

  public class StratBand { private static volatile ImmutableList<StratBand> stratBands = importFromDb(); static { MyEventBus.get().register(new Object() { @Subscribe public void refresh(ParameterRefreshEvent e) { stratBands = importFromDb(); } }); } private final int minRange; private final int maxRange; private static ImmutableList<StratBand> importFromDb() { //construct list from database here } //constructors, methods, etc } 
+6
source share
1 answer

So I wonder if kosher use a static initializer

The funny thing is that

 private static final boolean subscribed = subscribe(); 

and

 private static final boolean subscribed; static { subscribed = subscribe(); } 

Get the exact same bytecode compiled. Therefore, the use of an unnecessary static variable is strictly worse.


But until we’re ready to scale to a DI-driven framework,

Open Guice . Do not call it a framework (although it is). It is easy to use and allows you to get rid of static .

Or do it manually. Rewrite your class by dropping all static modifiers and passing them wherever needed. This is pretty verbose, but specifying dependencies explicitly allows you to test classes in isolation.

Be that as it may, you cannot test StratBand without getting into the database, no matter how trivial the test method is. The problem is combining each instance of StratBand with a list of all StratBand s.

In addition, you cannot check the behavior depending on the contents of stratBands , since it is always loaded from the database (of course, you can populate your database accordingly, but this is a big pain).

First, I would create a StratBandManager (or stratBands or any other name) and move all the static functions. To facilitate the transition, I would create a temporary class with static helpers, for example

 private static StratBandManager stratBandManager = new StratBandManager(); public static ImmutableList<StratBand> stratBands() { return stratBandManager.stratBands(); } 

Then discount it all and replace it with DI (using Guice or do it manually).


I find Guice useful even for small projects. The overhead is tiny, because often there is little or no configuration.

+3
source

Source: https://habr.com/ru/post/984754/


All Articles