Skip to content

Commit 0b6a7bf

Browse files
authored
Deprecate JsonElement constructor (#1761)
* Deprecate JsonElement constructor Creating custom JsonElement subclasses is discouraged. * Improve test and documentation * Improve JsonTreeReaderTest, adjust deprecation comments
1 parent a1d2ebc commit 0b6a7bf

File tree

7 files changed

+64
-9
lines changed

7 files changed

+64
-9
lines changed

gson/src/main/java/com/google/gson/JsonArray.java

+11-2
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,19 @@ public final class JsonArray extends JsonElement implements Iterable<JsonElement
3636
/**
3737
* Creates an empty JsonArray.
3838
*/
39+
@SuppressWarnings("deprecation") // superclass constructor
3940
public JsonArray() {
4041
elements = new ArrayList<>();
4142
}
42-
43+
44+
/**
45+
* Creates an empty JsonArray with the desired initial capacity.
46+
*
47+
* @param capacity initial capacity.
48+
* @throws IllegalArgumentException if the {@code capacity} is
49+
* negative
50+
*/
51+
@SuppressWarnings("deprecation") // superclass constructor
4352
public JsonArray(int capacity) {
4453
elements = new ArrayList<>(capacity);
4554
}
@@ -171,7 +180,7 @@ public boolean contains(JsonElement element) {
171180
public int size() {
172181
return elements.size();
173182
}
174-
183+
175184
/**
176185
* Returns true if the array is empty
177186
*

gson/src/main/java/com/google/gson/JsonElement.java

+9
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@
3131
* @author Joel Leitch
3232
*/
3333
public abstract class JsonElement {
34+
/**
35+
* @deprecated Creating custom {@code JsonElement} subclasses is highly discouraged
36+
* and can lead to undefined behavior.<br>
37+
* This constructor is only kept for backward compatibility.
38+
*/
39+
@Deprecated
40+
public JsonElement() {
41+
}
42+
3443
/**
3544
* Returns a deep copy of this element. Immutable elements like primitives
3645
* and nulls are not copied.

gson/src/main/java/com/google/gson/JsonNull.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,16 @@
2525
*/
2626
public final class JsonNull extends JsonElement {
2727
/**
28-
* singleton for JsonNull
28+
* Singleton for JsonNull
2929
*
3030
* @since 1.8
3131
*/
3232
public static final JsonNull INSTANCE = new JsonNull();
3333

3434
/**
3535
* Creates a new JsonNull object.
36-
* Deprecated since Gson version 1.8. Use {@link #INSTANCE} instead
36+
*
37+
* @deprecated Deprecated since Gson version 1.8. Use {@link #INSTANCE} instead
3738
*/
3839
@Deprecated
3940
public JsonNull() {

gson/src/main/java/com/google/gson/JsonObject.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package com.google.gson;
1818

1919
import com.google.gson.internal.LinkedTreeMap;
20-
2120
import java.util.Map;
2221
import java.util.Set;
2322

@@ -32,6 +31,13 @@
3231
public final class JsonObject extends JsonElement {
3332
private final LinkedTreeMap<String, JsonElement> members = new LinkedTreeMap<>();
3433

34+
/**
35+
* Creates an empty JsonObject.
36+
*/
37+
@SuppressWarnings("deprecation") // superclass constructor
38+
public JsonObject() {
39+
}
40+
3541
/**
3642
* Creates a deep copy of this element and all its children
3743
* @since 2.8.2

gson/src/main/java/com/google/gson/JsonPrimitive.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@
1717
package com.google.gson;
1818

1919
import com.google.gson.internal.$Gson$Preconditions;
20+
import com.google.gson.internal.LazilyParsedNumber;
2021
import java.math.BigDecimal;
2122
import java.math.BigInteger;
2223

23-
import com.google.gson.internal.LazilyParsedNumber;
24-
2524
/**
2625
* A class representing a Json primitive value. A primitive value
2726
* is either a String, a Java primitive, or a Java primitive
@@ -39,6 +38,7 @@ public final class JsonPrimitive extends JsonElement {
3938
*
4039
* @param bool the value to create the primitive with.
4140
*/
41+
@SuppressWarnings("deprecation") // superclass constructor
4242
public JsonPrimitive(Boolean bool) {
4343
value = $Gson$Preconditions.checkNotNull(bool);
4444
}
@@ -48,6 +48,7 @@ public JsonPrimitive(Boolean bool) {
4848
*
4949
* @param number the value to create the primitive with.
5050
*/
51+
@SuppressWarnings("deprecation") // superclass constructor
5152
public JsonPrimitive(Number number) {
5253
value = $Gson$Preconditions.checkNotNull(number);
5354
}
@@ -57,6 +58,7 @@ public JsonPrimitive(Number number) {
5758
*
5859
* @param string the value to create the primitive with.
5960
*/
61+
@SuppressWarnings("deprecation") // superclass constructor
6062
public JsonPrimitive(String string) {
6163
value = $Gson$Preconditions.checkNotNull(string);
6264
}
@@ -67,6 +69,7 @@ public JsonPrimitive(String string) {
6769
*
6870
* @param c the value to create the primitive with.
6971
*/
72+
@SuppressWarnings("deprecation") // superclass constructor
7073
public JsonPrimitive(Character c) {
7174
// convert characters to strings since in JSON, characters are represented as a single
7275
// character string

gson/src/main/java/com/google/gson/internal/bind/JsonTreeReader.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@
2323
import com.google.gson.JsonPrimitive;
2424
import com.google.gson.stream.JsonReader;
2525
import com.google.gson.stream.JsonToken;
26+
import com.google.gson.stream.MalformedJsonException;
2627
import java.io.IOException;
2728
import java.io.Reader;
29+
import java.util.Arrays;
2830
import java.util.Iterator;
2931
import java.util.Map;
30-
import java.util.Arrays;
3132

3233
/**
3334
* This reader walks the elements of a JsonElement as if it was coming from a
@@ -143,7 +144,7 @@ public JsonTreeReader(JsonElement element) {
143144
} else if (o == SENTINEL_CLOSED) {
144145
throw new IllegalStateException("JsonReader is closed");
145146
} else {
146-
throw new AssertionError();
147+
throw new MalformedJsonException("Custom JsonElement subclass " + o.getClass().getName() + " is not supported");
147148
}
148149
}
149150

gson/src/test/java/com/google/gson/internal/bind/JsonTreeReaderTest.java

+26
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
package com.google.gson.internal.bind;
1717

1818
import com.google.gson.JsonArray;
19+
import com.google.gson.JsonElement;
1920
import com.google.gson.JsonNull;
2021
import com.google.gson.JsonObject;
2122
import com.google.gson.stream.JsonToken;
23+
import com.google.gson.stream.MalformedJsonException;
2224
import java.io.IOException;
2325
import junit.framework.TestCase;
2426

@@ -54,4 +56,28 @@ public void testHasNext_endOfDocument() throws IOException {
5456
reader.endObject();
5557
assertFalse(reader.hasNext());
5658
}
59+
60+
public void testCustomJsonElementSubclass() throws IOException {
61+
@SuppressWarnings("deprecation") // superclass constructor
62+
class CustomSubclass extends JsonElement {
63+
@Override
64+
public JsonElement deepCopy() {
65+
return this;
66+
}
67+
}
68+
69+
JsonArray array = new JsonArray();
70+
array.add(new CustomSubclass());
71+
72+
JsonTreeReader reader = new JsonTreeReader(array);
73+
reader.beginArray();
74+
try {
75+
// Should fail due to custom JsonElement subclass
76+
reader.peek();
77+
fail();
78+
} catch (MalformedJsonException expected) {
79+
assertEquals("Custom JsonElement subclass " + CustomSubclass.class.getName() + " is not supported",
80+
expected.getMessage());
81+
}
82+
}
5783
}

0 commit comments

Comments
 (0)