1 /*
2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug 5043030
27  * @summary Verify that the method java.lang.reflect.Field.get(Object) makes
28  *          use of the same caching mechanism as used for autoboxing
29  *          when wrapping values of the primitive types.
30  * @author Andrej Golovnin
31  */
32 
33 import java.lang.reflect.Field;
34 
35 public class TestFieldReflectValueOf {
36 
37     @SuppressWarnings("unused")
38     private static boolean booleanStaticField;
39     @SuppressWarnings("unused")
40     private static byte byteStaticField;
41     @SuppressWarnings("unused")
42     private static char charStaticField;
43     @SuppressWarnings("unused")
44     private static int intStaticField;
45     @SuppressWarnings("unused")
46     private static long longStaticField;
47     @SuppressWarnings("unused")
48     private static short shortStaticField;
49 
50     @SuppressWarnings("unused")
51     private static volatile boolean booleanStaticVolatileField;
52     @SuppressWarnings("unused")
53     private static volatile byte byteStaticVolatileField;
54     @SuppressWarnings("unused")
55     private static volatile char charStaticVolatileField;
56     @SuppressWarnings("unused")
57     private static volatile int intStaticVolatileField;
58     @SuppressWarnings("unused")
59     private static volatile long longStaticVolatileField;
60     @SuppressWarnings("unused")
61     private static volatile short shortStaticVolatileField;
62 
63     @SuppressWarnings("unused")
64     private boolean booleanField;
65     @SuppressWarnings("unused")
66     private byte byteField;
67     @SuppressWarnings("unused")
68     private char charField;
69     @SuppressWarnings("unused")
70     private int intField;
71     @SuppressWarnings("unused")
72     private long longField;
73     @SuppressWarnings("unused")
74     private short shortField;
75 
76     @SuppressWarnings("unused")
77     private volatile boolean booleanVolatileField;
78     @SuppressWarnings("unused")
79     private volatile byte byteVolatileField;
80     @SuppressWarnings("unused")
81     private volatile char charVolatileField;
82     @SuppressWarnings("unused")
83     private volatile int intVolatileField;
84     @SuppressWarnings("unused")
85     private volatile long longVolatileField;
86     @SuppressWarnings("unused")
87     private volatile short shortVolatileField;
88 
main(String[] args)89     public static void main(String[] args) {
90         testUnsafeStaticFieldAccessors();
91         testUnsafeQualifiedStaticFieldAccessors();
92         testUnsafeFieldAccessors();
93         testUnsafeQualifiedFieldAccessors();
94     }
95 
testUnsafeStaticFieldAccessors()96     private static void testUnsafeStaticFieldAccessors() {
97         testFieldAccessors(true, false);
98     }
99 
testUnsafeQualifiedStaticFieldAccessors()100     private static void testUnsafeQualifiedStaticFieldAccessors() {
101         testFieldAccessors(true, true);
102     }
103 
testUnsafeFieldAccessors()104     private static void testUnsafeFieldAccessors() {
105         testFieldAccessors(false, false);
106     }
107 
testUnsafeQualifiedFieldAccessors()108     private static void testUnsafeQualifiedFieldAccessors() {
109         testFieldAccessors(false, true);
110     }
111 
testFieldAccessors(boolean checkStatic, boolean checkVolatile)112     private static void testFieldAccessors(boolean checkStatic,
113         boolean checkVolatile)
114     {
115         // Boolean#valueOf test
116         testField(Boolean.TYPE, Boolean.FALSE, checkStatic, checkVolatile);
117         testField(Boolean.TYPE, Boolean.TRUE, checkStatic, checkVolatile);
118 
119         // Byte#valueOf test
120         for (int b = Byte.MIN_VALUE; b < (Byte.MAX_VALUE + 1); b++) {
121             testField(Byte.TYPE, Byte.valueOf((byte) b), checkStatic, checkVolatile);
122         }
123 
124         // Character#valueOf test
125         for (char c = '\u0000'; c <= '\u007F'; c++) {
126             testField(Character.TYPE, Character.valueOf(c), checkStatic, checkVolatile);
127         }
128 
129         // Integer#valueOf test
130         for (int i = -128; i <= 127; i++) {
131             testField(Integer.TYPE, Integer.valueOf(i), checkStatic, checkVolatile);
132         }
133 
134         // Long#valueOf test
135         for (long l = -128L; l <= 127L; l++) {
136             testField(Long.TYPE, Long.valueOf(l), checkStatic, checkVolatile);
137         }
138 
139         // Short#valueOf test
140         for (short s = -128; s <= 127; s++) {
141             testField(Short.TYPE, Short.valueOf(s), checkStatic, checkVolatile);
142         }
143     }
144 
testField(Class<?> primType, Object wrappedValue, boolean checkStatic, boolean checkVolatile)145     private static void testField(Class<?> primType, Object wrappedValue,
146         boolean checkStatic, boolean checkVolatile)
147     {
148         String fieldName = primType.getName();
149         if (checkStatic) {
150             fieldName += "Static";
151         }
152         if (checkVolatile) {
153             fieldName += "Volatile";
154         }
155         fieldName += "Field";
156         try {
157             Field field = TestFieldReflectValueOf.class.getDeclaredField(fieldName);
158             field.setAccessible(true);
159             TestFieldReflectValueOf obj = new TestFieldReflectValueOf();
160             field.set(obj, wrappedValue);
161             Object result = field.get(obj);
162             if (result != wrappedValue) {
163                 throw new RuntimeException("The value " + wrappedValue
164                     + " is not cached for the type " + primType);
165             }
166         } catch (  NoSuchFieldException | SecurityException
167                  | IllegalAccessException | IllegalArgumentException e)
168         {
169             throw new RuntimeException(e);
170         }
171     }
172 
173 }
174