Revised equals and hashcode of ObjectTypePair to ensure reference equality of object instead of value equality. Improved JavaDocs for various 1.4 API methods.

This commit is contained in:
Inderjeet Singh 2009-10-05 18:17:52 +00:00
parent 2716d96516
commit ff74224815
9 changed files with 90 additions and 49 deletions

View File

@ -64,7 +64,10 @@ public enum FieldNamingPolicy {
* <li>aStringField ---> a-string-field</li>
* <li>aURL ---> a-u-r-l</li>
* </ul>
*
* Using dashes in JavaScript is not recommended since dash is also used for a minus sign in
* expressions. This requires that a field named with dashes is always accessed as a quoted
* property like {@code myobject['my-field']}. Accessing it as an object field
* {@code myobject.my-field} will result in an unintended javascript expression.
* @since 1.4
*/
LOWER_CASE_WITH_DASHES(new LowerCamelCaseSeparatorNamingPolicy("-"));

View File

@ -187,13 +187,12 @@ public final class Gson {
/**
* This method serializes the specified object into its equivalent representation as a tree of
* {JsonElement}s. This method should be used when the specified object is not a generic type.
* This method uses {@link Class#getClass()} to get the type for the specified object, but the
* {@code getClass()} loses the generic type information because of the Type Erasure feature
* {@link JsonElement}s. This method should be used when the specified object is not a generic
* type. This method uses {@link Class#getClass()} to get the type for the specified object, but
* the {@code getClass()} loses the generic type information because of the Type Erasure feature
* of Java. Note that this method works fine if the any of the object fields are of generic type,
* just the object itself should not be of a generic type. If the object is of generic type, use
* {@link #toJson(Object, Type)} instead. If you want to write out the object to a
* {@link Writer}, use {@link #toJson(Object, Appendable)} instead.
* {@link #toJsonTree(Object, Type)} instead.
*
* @param src the object for which Json representation is to be created setting for Gson
* @return Json representation of {@code src}.
@ -209,9 +208,8 @@ public final class Gson {
/**
* This method serializes the specified object, including those of generic types, into its
* equivalent representation as a tree of {@link JsonElement}s. This method must be used if the
* specified object is a generic type. For non-generic objects, use {@link #toJson(Object)}
* instead. If you want to write out the object to a {@link Appendable},
* use {@link #toJson(Object, Type, Appendable)} instead.
* specified object is a generic type. For non-generic objects, use {@link #toJsonTree(Object)}
* instead.
*
* @param src the object for which JSON representation is to be created
* @param typeOfSrc The specific genericized type of src. You can obtain
@ -321,7 +319,7 @@ public final class Gson {
/**
* Converts a tree of {@link JsonElement}s into its equivalent JSON representation.
*
* @param jsonElement root of the tree of {@link JsonElement}s
* @param jsonElement root of a tree of {@link JsonElement}s
* @return JSON String representation of the tree
* @since 1.4
*/
@ -332,9 +330,9 @@ public final class Gson {
}
/**
* Writes out the equivalent JSON for the tree of {@link JsonElement}s.
* Writes out the equivalent JSON for a tree of {@link JsonElement}s.
*
* @param jsonElement root of the tree of {@link JsonElement}s
* @param jsonElement root of a tree of {@link JsonElement}s
* @param writer Writer to which the Json representation needs to be written
* @since 1.4
*/

View File

@ -150,7 +150,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
}
private void addAsArrayElement(ObjectTypePair elementTypePair) {
if (elementTypePair.getObj() == null) {
if (elementTypePair.getObject() == null) {
root.getAsJsonArray().add(JsonNull.createJsonNull());
} else {
JsonElement childElement = getJsonElementForChild(elementTypePair);
@ -169,7 +169,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
@SuppressWarnings("unchecked")
public boolean visitUsingCustomHandler(ObjectTypePair objTypePair) {
try {
Object obj = objTypePair.getObj();
Object obj = objTypePair.getObject();
Type objType = objTypePair.getType();
JsonSerializer serializer = serializers.getHandlerFor(objType);
if (serializer == null && obj != null) {
@ -194,7 +194,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
private JsonElement invokeCustomHandler(ObjectTypePair objTypePair, JsonSerializer serializer) {
start(objTypePair);
try {
return serializer.serialize(objTypePair.getObj(), objTypePair.getType(), context);
return serializer.serialize(objTypePair.getObject(), objTypePair.getType(), context);
} finally {
end(objTypePair);
}

View File

@ -25,14 +25,12 @@ import java.util.NoSuchElementException;
* A streaming parser that allows reading of multiple {@link JsonElement}s from the specified reader
* asynchronously.
*
* <p>This class is thread-compatible. For some more literature on these definitions, refer to
* Effective Java.
*
* <p>To properly use this class across multiple thread, you will need to add some external
* synchronization to your classes/thread to get this to work properly. For example:
* <p>This class is conditionally thread-safe (see Item 70, Effective Java second edition). To
* properly use this class across multiple threads, you will need to add some external
* synchronization. For example:
*
* <pre>
* JsonStreamParser parser = new JsonStreamParser("blah blah blah");
* JsonStreamParser parser = new JsonStreamParser("['first'] {'second':10} 'third'");
* JsonElement element;
* synchronized (someCommonObject) {
* if (parser.hasNext()) {
@ -104,6 +102,11 @@ public final class JsonStreamParser implements Iterator<JsonElement> {
}
}
/**
* Returns true if a {@link JsonElement} is available on the input for consumption
* @return true if a {@link JsonElement} is available on the input, false otherwise
* @since 1.4
*/
public boolean hasNext() {
synchronized (lock) {
try {
@ -116,6 +119,11 @@ public final class JsonStreamParser implements Iterator<JsonElement> {
}
}
/**
* This optional {@link Iterator} method is not relevant for stream parsing and hence is not
* implemented.
* @since 1.4
*/
public void remove() {
throw new UnsupportedOperationException();
}

View File

@ -77,7 +77,8 @@ final class MemoryRefStack {
}
for (ObjectTypePair stackObject : stack) {
if (stackObject.getObj() == obj.getObj() && stackObject.getType().equals(obj.getType()) ) {
if (stackObject.getObject() == obj.getObject()
&& stackObject.getType().equals(obj.getType()) ) {
return true;
}
}

View File

@ -93,7 +93,7 @@ final class ObjectNavigator {
public void accept(Visitor visitor) {
boolean visitedWithCustomHandler = visitor.visitUsingCustomHandler(objTypePair);
if (!visitedWithCustomHandler) {
Object obj = objTypePair.getObj();
Object obj = objTypePair.getObject();
Object objectToVisit = (obj == null) ? visitor.getTarget() : obj;
if (objectToVisit == null) {
return;

View File

@ -1,47 +1,79 @@
/*
* Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.gson;
import java.lang.reflect.Type;
final class ObjectTypePair {
/**
* A holder class for an object and its type
*
* @author Inderjeet Singh
*/
final class ObjectTypePair {
private static final int PRIME = 31;
private final Object obj;
private final Type type;
public ObjectTypePair(Object obj, Type type) {
this.obj = obj;
this.type = type;
}
public Object getObj() {
public Object getObject() {
return obj;
}
public Type getType() {
return type;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((obj == null) ? 0 : obj.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
// Not using type.hashCode() since I am not sure if the subclasses of type reimplement
// hashCode() to be equal for equal types
return ((obj == null) ? PRIME : obj.hashCode());
}
@Override
public boolean equals(Object obj) {
if (this == obj)
if (this == obj) {
return true;
if (obj == null)
}
if (obj == null) {
return false;
if (getClass() != obj.getClass())
}
if (getClass() != obj.getClass()) {
return false;
}
ObjectTypePair other = (ObjectTypePair) obj;
if (this.obj == null) {
if (other.obj != null)
if (other.obj != null) {
return false;
} else if (!this.obj.equals(other.obj))
}
} else if (this.obj != other.obj) { // Checking for reference equality
return false;
}
if (type == null) {
if (other.type != null)
if (other.type != null) {
return false;
} else if (!type.equals(other.type))
}
} else if (!type.equals(other.type)) {
return false;
}
return true;
}
}

View File

@ -62,17 +62,17 @@ import java.lang.annotation.Target;
public @interface Expose {
/**
* If true, the field marked with this annotation is written out in the JSON while serializing.
* If false, the field marked with this annotation is skipped from the serialized output.
* Defaults to true.
* If {@code true}, the field marked with this annotation is written out in the JSON while
* serializing. If {@code false}, the field marked with this annotation is skipped from the
* serialized output. Defaults to {@code true}.
* @since 1.4
*/
public boolean serialize() default true;
/**
* If true, the field marked with this annotation is deserialized from the JSON.
* If false, the field marked with this annotation is skipped during deserialization.
* Defaults to true.
* If {@code true}, the field marked with this annotation is deserialized from the JSON.
* If {@code false}, the field marked with this annotation is skipped during deserialization.
* Defaults to {@code true}.
* @since 1.4
*/
public boolean deserialize() default true;

View File

@ -61,13 +61,12 @@ public class MemoryRefStackTest extends TestCase {
}
public void testContains() throws Exception {
ObjectTypePair objA = new ObjectTypePair(new MockObject(), MockObject.class);
ObjectTypePair objB = new ObjectTypePair(new MockObject(), MockObject.class);
MockObject objA = new MockObject();
MockObject objB = new MockObject();
assertEquals(objA, objB);
stack.push(objA);
assertFalse(stack.contains(objB));
assertTrue(stack.contains(objA));
stack.push(new ObjectTypePair(objA, MockObject.class));
assertTrue(stack.contains(new ObjectTypePair(objA, MockObject.class)));
assertFalse(stack.contains(new ObjectTypePair(objB, MockObject.class)));
}
private static class MockObject {