简体   繁体   中英

Performance/treatment of static references to class instances

I've been toying with the following java pattern lately, it's helped solve a few code organization issues but I have multiple questions about best practices, performance, etc.

public class Example {

    private static int[] somethingList = int[128];

    public static final Example somethingOne = new Example(1);
    public static final Example somethingTwo = new Example(2);
    public static final ExampleChild somethingThree = new ExampleChild(3); // ExampleChild would extend Example

    private Example( int id ){
        // checks for existing id, etc
        somethingList[id] = this;
    }

    public static Example getById( int id ){
        return somethingList[id];
    }
}

The class registers a list of things to static variables, but has a private constructor also saving a list by id # to an array. Minecraft is one example of where this is used in the wild - for their item class "registry".

A few questions:

  • If there's no single instance of Example saved anywhere outside this, do calls to either Example.somethingOne or Example.getById() re-run all of this code, or is this all just run once? Maybe I'm missing some understanding of static ?
  • Is there any reason why you'd want the static instances of somethingOne to be public, rather than just calling it by id? Seems like getById is friendly if you have mods/plugins added custom items to the list that do not have static references by name here.

If there's no single instance of Example saved anywhere outside this, do calls to either Example.somethingOne or Example.getById() re-run all of this code, or is this all just run once? Maybe I'm missing some understanding of static?

No, static blocks are run at class load time and are tied to the instance of java.lang.Class which represents the class itself.

Classes are lazily loaded, but once loaded, never reload within the life of their class loader.

There is no performance loss by calling a static method or accessing a static variable instead of using an instance of it.

Is there any reason why you'd want the static instances of somethingOne to be public, rather than just calling it by id? Seems like getById is friendly if you have mods/plugins added custom items to the list that do not have static references by name here.

You kind of answered your own question here. Running access through a method enables the future addition of modules/plugins or some other work without having to refactor calling code.

One reason, however, that I may want the instances to be static members is if calling code needs to interact with specific instances and not others and you simply want your class to be able to control what those instances are, perhaps so you can add new instances when you want to.

Enums are a good example of this.

I have used the exact pattern you have above for a dynamic enum, where what I wanted was an enum, but I needed certain instances to be of sub-types and clients to not worry about it.

Since the only place where the private constructor is invoked is in the static declaration of somethingOne and somethingTwo , this constructor will be invoked the first time the class is used, which is what would trigger the loading of the class and the execution of the static code.

This would execute every time the class is initialized, which means that in a typical scenario where you use the default class loading provided by Java, this would only be invoked once no matter how many times you access the fields.

You may want to read the JLS 12.4 Initialization of Classes and Interfaces and JVMS 5.5 Initialization .

Not sure why the static instances are public, they could perfectly be private static final and by invoking the getId method the first time you would trigger the initialization of the class and obtain the same results. Maybe this is just convenience, after all the fields are static and final, so why not provide direct access to them?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM