001/* 002 * Copyright 2015 The Error Prone Authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.google.errorprone.annotations.concurrent; 017 018import static javax.lang.model.element.Modifier.FINAL; 019 020import java.lang.annotation.ElementType; 021import java.lang.annotation.Retention; 022import java.lang.annotation.RetentionPolicy; 023import java.lang.annotation.Target; 024 025/** 026 * Use this annotation on any static or field that will be initialized lazily, where races yield no 027 * semantic difference in the code (as, for example, is the case with {@link String#hashCode}). Note 028 * that lazily initializing a non-volatile field is hard to do correctly, and one should rarely use 029 * this. It should also only be done by developers who clearly understand the potential issues, and 030 * then, always using the pattern as presented in the {@code getData} method of this sample code 031 * below: 032 * 033 * <pre>{@code 034 * private final String source; 035 * {@literal @}LazyInit private String data; 036 * 037 * public String getData() { 038 * String local = data; 039 * if (local == null) { 040 * local = data = expensiveCalculation(source); 041 * } 042 * return local; 043 * } 044 * 045 * private static String expensiveCalculation(String string) { 046 * return string.replaceAll(" ", "_"); 047 * } 048 * }</pre> 049 * 050 * <p>The need for using the {@code local} variable is detailed in 051 * http://jeremymanson.blogspot.com/2008/12/benign-data-races-in-java.html (see, particularly, the 052 * part after "Now, let's break the code"). 053 * 054 * <p>Also note that {@code LazyInit} must not be used on 64-bit primitives ({@code long}s and 055 * {@code double}s), because the Java Language Specification does not guarantee that writing to 056 * these is atomic. Furthermore, when used for non-primitives, the non-primitive must be either 057 * truly immutable or at least thread safe (in the Java memory model sense). And callers must 058 * accommodate the fact that different calls to something like the above getData() method may return 059 * different (though identically computed) objects, with different identityHashCode() values. Again, 060 * unless you really understand this <b>and</b> you really need the performance benefits of 061 * introducing the data race, do not use this construct. 062 */ 063@Retention(RetentionPolicy.SOURCE) 064@Target(ElementType.FIELD) 065public @interface LazyInit {}