Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8254271: Development to deprecate wrapper class constructors for removal #221

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/java.base/share/classes/java/lang/Boolean.java
Original file line number Diff line number Diff line change
@@ -98,7 +98,7 @@ public final class Boolean implements java.io.Serializable,
* Also consider using the final fields {@link #TRUE} and {@link #FALSE}
* if possible.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Boolean(boolean value) {
this.value = value;
}
@@ -118,7 +118,7 @@ public Boolean(boolean value) {
* {@code boolean} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Boolean} object.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Boolean(String s) {
this(parseBoolean(s));
}
4 changes: 2 additions & 2 deletions src/java.base/share/classes/java/lang/Byte.java
Original file line number Diff line number Diff line change
@@ -337,7 +337,7 @@ public static Byte decode(String nm) throws NumberFormatException {
* {@link #valueOf(byte)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Byte(byte value) {
this.value = value;
}
@@ -360,7 +360,7 @@ public Byte(byte value) {
* {@code byte} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Byte} object.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Byte(String s) throws NumberFormatException {
this.value = parseByte(s, 10);
}
2 changes: 1 addition & 1 deletion src/java.base/share/classes/java/lang/Character.java
Original file line number Diff line number Diff line change
@@ -8501,7 +8501,7 @@ public static final UnicodeScript forName(String scriptName) {
* {@link #valueOf(char)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Character(char value) {
this.value = value;
}
4 changes: 2 additions & 2 deletions src/java.base/share/classes/java/lang/Double.java
Original file line number Diff line number Diff line change
@@ -605,7 +605,7 @@ public static boolean isFinite(double d) {
* {@link #valueOf(double)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Double(double value) {
this.value = value;
}
@@ -626,7 +626,7 @@ public Double(double value) {
* {@code double} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Double} object.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Double(String s) throws NumberFormatException {
value = parseDouble(s);
}
6 changes: 3 additions & 3 deletions src/java.base/share/classes/java/lang/Float.java
Original file line number Diff line number Diff line change
@@ -518,7 +518,7 @@ public static boolean isFinite(float f) {
* {@link #valueOf(float)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Float(float value) {
this.value = value;
}
@@ -534,7 +534,7 @@ public Float(float value) {
* static factory method {@link #valueOf(float)} method as follows:
* {@code Float.valueOf((float)value)}.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Float(double value) {
this.value = (float)value;
}
@@ -555,7 +555,7 @@ public Float(double value) {
* {@code float} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Float} object.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Float(String s) throws NumberFormatException {
value = parseFloat(s);
}
4 changes: 2 additions & 2 deletions src/java.base/share/classes/java/lang/Integer.java
Original file line number Diff line number Diff line change
@@ -1085,7 +1085,7 @@ public static Integer valueOf(int i) {
* {@link #valueOf(int)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Integer(int value) {
this.value = value;
}
@@ -1107,7 +1107,7 @@ public Integer(int value) {
* {@code int} primitive, or use {@link #valueOf(String)}
* to convert a string to an {@code Integer} object.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}
4 changes: 2 additions & 2 deletions src/java.base/share/classes/java/lang/Long.java
Original file line number Diff line number Diff line change
@@ -1316,7 +1316,7 @@ else if (nm.startsWith("0", index) && nm.length() > 1 + index) {
* {@link #valueOf(long)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Long(long value) {
this.value = value;
}
@@ -1339,7 +1339,7 @@ public Long(long value) {
* {@code long} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Long} object.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Long(String s) throws NumberFormatException {
this.value = parseLong(s, 10);
}
4 changes: 2 additions & 2 deletions src/java.base/share/classes/java/lang/Short.java
Original file line number Diff line number Diff line change
@@ -342,7 +342,7 @@ public static Short decode(String nm) throws NumberFormatException {
* {@link #valueOf(short)} is generally a better choice, as it is
* likely to yield significantly better space and time performance.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Short(short value) {
this.value = value;
}
@@ -365,7 +365,7 @@ public Short(short value) {
* {@code short} primitive, or use {@link #valueOf(String)}
* to convert a string to a {@code Short} object.
*/
@Deprecated(since="9")
@Deprecated(since="9", forRemoval = true)
public Short(String s) throws NumberFormatException {
this.value = parseShort(s, 10);
}
Original file line number Diff line number Diff line change
@@ -773,7 +773,7 @@ public MemberName getDefinition() {
}

@Override
@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "removal"})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's going to happen to these warning suppressions when we actually remove (make private) the constructors? Is the intent to just defer that problem until it happens?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the code is changed to not use the constructors, the warning (deprecation and remove) should be removed.
Some of the code is upstream and requires more changes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should change MemberName to call the factory method Byte::valueof (that's JDK code).

For the Graal change, you are touching the code anyway -- I think changing them to use the factory methods would be better than adding "removal" to the suppression. But it may be better to check if these tests intentionally test with the public constructors to test for JIT optimization before applying the change.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, Mandy replied to the question I should have asked: for all the suppressed "removal" points, what is the plan to fix the offending code? If not now, when? ("Later" may be a reasonable answer, but fleshing out the followup tasks would be helpful.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment in MemberName makes it clear that hashCode method may be called before the cache is setup and valueOf uses the cache.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its up to the Graal folks to replace their code. In some cases, they are depending on Identity semantics of new Integer().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification. Can you file a JBS issue to Graal to make change in its upstream project?

public int hashCode() {
// Avoid autoboxing getReferenceKind(), since this is used early and will force
// early initialization of Byte$ByteCache
Original file line number Diff line number Diff line change
@@ -258,7 +258,10 @@ public javax.management.ObjectInstance createMBean(java.lang.String $param_Strin
public javax.management.remote.NotificationResult fetchNotifications(long $param_long_1, int $param_int_2, long $param_long_3)
throws java.io.IOException {
try {
Object $result = ref.invoke(this, $method_fetchNotifications_7, new java.lang.Object[]{new java.lang.Long($param_long_1), new java.lang.Integer($param_int_2), new java.lang.Long($param_long_3)}, -5037523307973544478L);
Object $result = ref.invoke(this, $method_fetchNotifications_7,
new java.lang.Object[]{java.lang.Long.valueOf($param_long_1),
java.lang.Integer.valueOf($param_int_2),
java.lang.Long.valueOf($param_long_3)}, -5037523307973544478L);
return ((javax.management.remote.NotificationResult) $result);
} catch (java.lang.RuntimeException e) {
throw e;
Original file line number Diff line number Diff line change
@@ -4013,7 +4013,8 @@ else if (componentType.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP)) {
","+oldName:currSchema.fTargetNamespace+","+oldName;
int attGroupRefsCount = changeRedefineGroup(processedBaseName, componentType, newName, child, currSchema);
if (attGroupRefsCount > 1) {
reportSchemaError("src-redefine.7.1", new Object []{new Integer(attGroupRefsCount)}, child);
reportSchemaError("src-redefine.7.1",
new Object []{Integer.valueOf(attGroupRefsCount)}, child);
}
else if (attGroupRefsCount == 1) {
// return true;
@@ -4029,7 +4030,7 @@ else if (componentType.equals(SchemaSymbols.ELT_GROUP)) {
","+oldName:currSchema.fTargetNamespace+","+oldName;
int groupRefsCount = changeRedefineGroup(processedBaseName, componentType, newName, child, currSchema);
if (groupRefsCount > 1) {
reportSchemaError("src-redefine.6.1.1", new Object []{new Integer(groupRefsCount)}, child);
reportSchemaError("src-redefine.6.1.1", new Object []{Integer.valueOf(groupRefsCount)}, child);
}
else if (groupRefsCount == 1) {
// return true;
Original file line number Diff line number Diff line change
@@ -438,8 +438,8 @@ private static void initialize()
private static void defineEntity( String name, char value )
{
if ( _byName.get( name ) == null ) {
_byName.put( name, new Integer( value ) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure @JoeWang-Java reviews the XML changes; there are complications in some areas where the master code is upstream of the code in the JDK.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JAXP was subsumed by JSR 379 in Java SE 9.

_byChar.put( new Integer( value ), name );
_byName.put( name, Integer.valueOf( value ) );
_byChar.put( Integer.valueOf( value ), name );
}
}

Original file line number Diff line number Diff line change
@@ -133,7 +133,7 @@ public int hashCode(Object o) {
Assert.assertTrue(set.add(newInteger(0)));
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
private static Integer newInteger(int value) {
return new Integer(value);
}
Original file line number Diff line number Diff line change
@@ -161,7 +161,7 @@ public void testSetRemoval() {
Assert.assertEquals(newInteger(9), finalList.get(0));
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
private static Integer newInteger(int value) {
return new Integer(value);
}
Original file line number Diff line number Diff line change
@@ -58,7 +58,7 @@ public void test1() {
testEscapeAnalysis("test1Snippet", JavaConstant.forInt(101), false);
}

@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "removal"})
public static int test1Snippet() {
Integer x = new Integer(101);
return x.intValue();
@@ -89,7 +89,7 @@ public void testMonitor() {
testEscapeAnalysis("testMonitorSnippet", JavaConstant.forInt(0), false);
}

@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "removal"})
public static int testMonitorSnippet() {
Integer x = new Integer(0);
Double y = new Double(0);
@@ -113,7 +113,7 @@ public void testMonitor2() {
* This test case differs from the last one in that it requires inlining within a synchronized
* region.
*/
@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "removal"})
public static int testMonitor2Snippet() {
Integer x = new Integer(0);
Double y = new Double(0);
@@ -335,7 +335,7 @@ public void testChangeHandling() {

public volatile Object field;

@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "removal"})
public int testChangeHandlingSnippet(int a) {
Object obj;
Integer one = 1;
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ protected OptimisticOptimizations getOptimisticOptimizations() {

public static Object field;

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippet1(int i) {
Integer object = new Integer(i);
GraalDirectives.ensureVirtualized(object);
@@ -53,7 +53,7 @@ public void test1() {
test("snippet1", 1);
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippet2(int i) {
Integer object = new Integer(i);
GraalDirectives.ensureVirtualized(object);
@@ -65,7 +65,7 @@ public void test2() {
test("snippet2", 1);
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippet3(int i) {
Integer object = new Integer(i);
field = object;
@@ -77,7 +77,7 @@ public void test3() {
test("snippet3", 1);
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetHere1(int i) {
Integer object = new Integer(i);
GraalDirectives.ensureVirtualizedHere(object);
@@ -88,7 +88,7 @@ public void testHere1() {
test("snippetHere1", 1);
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetHere2(int i) {
Integer object = new Integer(i);
GraalDirectives.ensureVirtualizedHere(object);
@@ -100,7 +100,7 @@ public void testHere2() {
test("snippetHere2", 1);
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetHere3(int i) {
Integer object = new Integer(i);
field = object;
@@ -133,7 +133,7 @@ public void testBoxing2() {
test("snippetBoxing2", 1);
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetControlFlow1(boolean b, int i) {
Integer object = new Integer(i);
if (b) {
@@ -148,7 +148,7 @@ public void testControlFlow1() {
test("snippetControlFlow1", true, 1);
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetControlFlow2(boolean b, int i) {
Integer object = new Integer(i);
if (b) {
@@ -165,7 +165,7 @@ public void testControlFlow2() {
test("snippetControlFlow2", true, 1);
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetControlFlow3(boolean b, int i) {
Integer object = new Integer(i);
GraalDirectives.ensureVirtualized(object);
@@ -183,7 +183,7 @@ public void testControlFlow3() {
test("snippetControlFlow3", true, 1);
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetControlFlow4(boolean b, int i) {
Integer object = new Integer(i);
if (b) {
@@ -199,7 +199,7 @@ public void testControlFlow4() {
test("snippetControlFlow4", true, 1);
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetControlFlow5(boolean b, int i) {
Integer object = new Integer(i);
if (b) {
@@ -220,7 +220,7 @@ public static final class TestClass {
Object b;
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetIndirect1(boolean b, int i) {
Integer object = new Integer(i);
TestClass t = new TestClass();
@@ -239,7 +239,7 @@ public void testIndirect1() {
test("snippetIndirect1", true, 1);
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static void snippetIndirect2(boolean b, int i) {
Integer object = new Integer(i);
TestClass t = new TestClass();
Original file line number Diff line number Diff line change
@@ -115,7 +115,7 @@ public void test3() {
testPartialEscapeAnalysis("test3Snippet", 0.5, 1, StoreFieldNode.class, LoadFieldNode.class);
}

@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "removal"})
public static Object test3Snippet(int a) {
if (a < 0) {
TestObject obj = new TestObject(1, 2);
Original file line number Diff line number Diff line change
@@ -114,7 +114,7 @@ public void test02() {
assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class));
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
static void test03Entry() {
Data data = new Data();
data.f = new Integer(42);
@@ -142,7 +142,7 @@ public void test03() {
assertEquals(m(sa, B.class, "foo").getFormalReturn(), t(Data.class), t(Integer.class));
}

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
static void test04Entry() {
Data data = null;
for (int i = 0; i < 2; i++) {
Original file line number Diff line number Diff line change
@@ -386,13 +386,13 @@ public <T> T getFlag(String name, Class<T> type, T notPresent, boolean expectPre
// overhead when running with assertions enabled.
T sentinel;
if (type == Boolean.class) {
sentinel = type.cast(new Boolean(false));
sentinel = type.cast(false);
} else if (type == Byte.class) {
sentinel = type.cast(new Byte((byte) 123));
sentinel = type.cast((byte) 123);
} else if (type == Integer.class) {
sentinel = type.cast(new Integer(1234567890));
sentinel = type.cast(1234567890);
} else if (type == Long.class) {
sentinel = type.cast(new Long(1234567890987654321L));
sentinel = type.cast(1234567890987654321L);
} else if (type == String.class) {
sentinel = type.cast(new String("1234567890987654321"));
} else {
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@
*/
public class HP_allocate02 extends JTTTest {

@SuppressWarnings({"deprecation", "unused"})
@SuppressWarnings({"deprecation", "removal", "unused"})
public static int test(int count) {
int sum = 0;
for (int i = 0; i < count; i++) {
62 changes: 62 additions & 0 deletions test/jdk/java/lang/WrappersTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have historically not found it necessary to write tests to verify this kind of change and have instead relied on signature testing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1.

FWIW. You have also verified when you get the warnings from JDK build and needs to suppressed it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test can be removed but was a double check that all of the constructors of the named classes had been modified.

* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/


import org.testng.annotations.Test;

import java.lang.reflect.Constructor;
import java.util.List;

import static org.testng.Assert.*;

/*
* @test
* @bug 8252180
* @summary Test the primitive wrappers constructors are deprecated for removal
* @run testng WrappersTest
*/

@Test
public class WrappersTest {

@Test
void checkForDeprecated() {
List<Class<?>> classes =
List.of(Byte.class,
Short.class,
Integer.class,
Long.class,
Float.class,
Double.class,
Character.class,
Boolean.class);
for (Class<?> cl : classes) {
for (Constructor<?> cons : cl.getConstructors()) {
Deprecated dep = cons.getAnnotation(Deprecated.class);
assertNotNull(dep, "Missing @Deprecated annotation");
System.out.println(cons + ": " + dep);
assertTrue(dep.forRemoval(), cl.toString() + " deprecated for removal: ");
}
}
}
}