All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.errorprone.annotations.concurrent.LazyInit Maven / Gradle / Ivy

There is a newer version: 3.0.0-alpha-3
Show newest version
/*
 * Copyright 2015 The Error Prone Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.errorprone.annotations.concurrent;

import com.google.errorprone.annotations.IncompatibleModifiers;
import com.google.errorprone.annotations.Modifier;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Use this annotation on any static or field that will be initialized lazily, where races yield no
 * semantic difference in the code (as, for example, is the case with {@link String#hashCode}). Note
 * that lazily initializing a non-volatile field is hard to do correctly, and one should rarely use
 * this. It should also only be done by developers who clearly understand the potential issues, and
 * then, always using the pattern as presented in the {@code getData} method of this sample code
 * below:
 *
 * 
{@code
 * private final String source;
 * @LazyInit private String data;
 *
 * public String getData() {
 *   String local = data;
 *   if (local == null) {
 *     data = local = expensiveCalculation(source);
 *   }
 *   return local;
 *  }
 *
 * private static String expensiveCalculation(String string) {
 *   return string.replaceAll(" ", "_");
 * }
 * }
* *

The need for using the {@code local} variable is detailed in * http://jeremymanson.blogspot.com/2008/12/benign-data-races-in-java.html (see, particularly, the * part after "Now, let's break the code"). * *

Also note that {@code LazyInit} must not be used on 64-bit primitives ({@code long}s and * {@code double}s), because the Java Language Specification does not guarantee that writing to * these is atomic. Furthermore, when used for non-primitives, the non-primitive must be either * truly immutable or at least thread safe (in the Java memory model sense). And callers must * accommodate the fact that different calls to something like the above getData() method may return * different (though identically computed) objects, with different identityHashCode() values. Again, * unless you really understand this and you really need the performance benefits of * introducing the data race, do not use this construct. */ @IncompatibleModifiers(modifier = {Modifier.FINAL}) @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface LazyInit {}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy