Skip to content

Commit

Permalink
Deprecate JsonElement constructor (#1761)
Browse files Browse the repository at this point in the history
* Deprecate JsonElement constructor

Creating custom JsonElement subclasses is discouraged.

* Improve test and documentation

* Improve JsonTreeReaderTest, adjust deprecation comments
  • Loading branch information
Marcono1234 committed Aug 4, 2022
1 parent a1d2ebc commit 0b6a7bf
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 9 deletions.
13 changes: 11 additions & 2 deletions gson/src/main/java/com/google/gson/JsonArray.java
Expand Up @@ -36,10 +36,19 @@ public final class JsonArray extends JsonElement implements Iterable<JsonElement
/**
* Creates an empty JsonArray.
*/
@SuppressWarnings("deprecation") // superclass constructor
public JsonArray() {
elements = new ArrayList<>();
}


/**
* Creates an empty JsonArray with the desired initial capacity.
*
* @param capacity initial capacity.
* @throws IllegalArgumentException if the {@code capacity} is
* negative
*/
@SuppressWarnings("deprecation") // superclass constructor
public JsonArray(int capacity) {
elements = new ArrayList<>(capacity);
}
Expand Down Expand Up @@ -171,7 +180,7 @@ public boolean contains(JsonElement element) {
public int size() {
return elements.size();
}

/**
* Returns true if the array is empty
*
Expand Down
9 changes: 9 additions & 0 deletions gson/src/main/java/com/google/gson/JsonElement.java
Expand Up @@ -31,6 +31,15 @@
* @author Joel Leitch
*/
public abstract class JsonElement {
/**
* @deprecated Creating custom {@code JsonElement} subclasses is highly discouraged
* and can lead to undefined behavior.<br>
* This constructor is only kept for backward compatibility.
*/
@Deprecated
public JsonElement() {
}

/**
* Returns a deep copy of this element. Immutable elements like primitives
* and nulls are not copied.
Expand Down
5 changes: 3 additions & 2 deletions gson/src/main/java/com/google/gson/JsonNull.java
Expand Up @@ -25,15 +25,16 @@
*/
public final class JsonNull extends JsonElement {
/**
* singleton for JsonNull
* Singleton for JsonNull
*
* @since 1.8
*/
public static final JsonNull INSTANCE = new JsonNull();

/**
* Creates a new JsonNull object.
* Deprecated since Gson version 1.8. Use {@link #INSTANCE} instead
*
* @deprecated Deprecated since Gson version 1.8. Use {@link #INSTANCE} instead
*/
@Deprecated
public JsonNull() {
Expand Down
8 changes: 7 additions & 1 deletion gson/src/main/java/com/google/gson/JsonObject.java
Expand Up @@ -17,7 +17,6 @@
package com.google.gson;

import com.google.gson.internal.LinkedTreeMap;

import java.util.Map;
import java.util.Set;

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

/**
* Creates an empty JsonObject.
*/
@SuppressWarnings("deprecation") // superclass constructor
public JsonObject() {
}

/**
* Creates a deep copy of this element and all its children
* @since 2.8.2
Expand Down
7 changes: 5 additions & 2 deletions gson/src/main/java/com/google/gson/JsonPrimitive.java
Expand Up @@ -17,11 +17,10 @@
package com.google.gson;

import com.google.gson.internal.$Gson$Preconditions;
import com.google.gson.internal.LazilyParsedNumber;
import java.math.BigDecimal;
import java.math.BigInteger;

import com.google.gson.internal.LazilyParsedNumber;

/**
* A class representing a Json primitive value. A primitive value
* is either a String, a Java primitive, or a Java primitive
Expand All @@ -39,6 +38,7 @@ public final class JsonPrimitive extends JsonElement {
*
* @param bool the value to create the primitive with.
*/
@SuppressWarnings("deprecation") // superclass constructor
public JsonPrimitive(Boolean bool) {
value = $Gson$Preconditions.checkNotNull(bool);
}
Expand All @@ -48,6 +48,7 @@ public JsonPrimitive(Boolean bool) {
*
* @param number the value to create the primitive with.
*/
@SuppressWarnings("deprecation") // superclass constructor
public JsonPrimitive(Number number) {
value = $Gson$Preconditions.checkNotNull(number);
}
Expand All @@ -57,6 +58,7 @@ public JsonPrimitive(Number number) {
*
* @param string the value to create the primitive with.
*/
@SuppressWarnings("deprecation") // superclass constructor
public JsonPrimitive(String string) {
value = $Gson$Preconditions.checkNotNull(string);
}
Expand All @@ -67,6 +69,7 @@ public JsonPrimitive(String string) {
*
* @param c the value to create the primitive with.
*/
@SuppressWarnings("deprecation") // superclass constructor
public JsonPrimitive(Character c) {
// convert characters to strings since in JSON, characters are represented as a single
// character string
Expand Down
Expand Up @@ -23,11 +23,12 @@
import com.google.gson.JsonPrimitive;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.MalformedJsonException;
import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Arrays;

/**
* This reader walks the elements of a JsonElement as if it was coming from a
Expand Down Expand Up @@ -143,7 +144,7 @@ public JsonTreeReader(JsonElement element) {
} else if (o == SENTINEL_CLOSED) {
throw new IllegalStateException("JsonReader is closed");
} else {
throw new AssertionError();
throw new MalformedJsonException("Custom JsonElement subclass " + o.getClass().getName() + " is not supported");
}
}

Expand Down
Expand Up @@ -16,9 +16,11 @@
package com.google.gson.internal.bind;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.MalformedJsonException;
import java.io.IOException;
import junit.framework.TestCase;

Expand Down Expand Up @@ -54,4 +56,28 @@ public void testHasNext_endOfDocument() throws IOException {
reader.endObject();
assertFalse(reader.hasNext());
}

public void testCustomJsonElementSubclass() throws IOException {
@SuppressWarnings("deprecation") // superclass constructor
class CustomSubclass extends JsonElement {
@Override
public JsonElement deepCopy() {
return this;
}
}

JsonArray array = new JsonArray();
array.add(new CustomSubclass());

JsonTreeReader reader = new JsonTreeReader(array);
reader.beginArray();
try {
// Should fail due to custom JsonElement subclass
reader.peek();
fail();
} catch (MalformedJsonException expected) {
assertEquals("Custom JsonElement subclass " + CustomSubclass.class.getName() + " is not supported",
expected.getMessage());
}
}
}

0 comments on commit 0b6a7bf

Please sign in to comment.