From 6c68b0e56cb2cd9c3be30621c12e57d02630c0b8 Mon Sep 17 00:00:00 2001 From: CodePlayer Date: Sun, 17 Nov 2024 20:18:23 +0800 Subject: [PATCH] Improve some code details, fix some bugs (#3161) * refactor: reuse some methods * refactor: remove unused field * refactor: simplify some code * fix: a potential bug * style: add .gitattributes for code style * fix: issue#2848 and issue#2988 --- .gitattributes | 1 + .../java/com/alibaba/fastjson2/JSONArray.java | 1 - .../java/com/alibaba/fastjson2/JSONBDump.java | 1 - .../com/alibaba/fastjson2/JSONObject.java | 186 ++++-------------- .../alibaba/fastjson2/JSONPathFunction.java | 5 +- .../com/alibaba/fastjson2/JSONReader.java | 16 +- .../alibaba/fastjson2/JSONReaderUTF16.java | 8 +- .../com/alibaba/fastjson2/JSONReaderUTF8.java | 7 +- .../alibaba/fastjson2/JSONWriterJSONB.java | 9 +- .../alibaba/fastjson2/reader/FieldReader.java | 5 +- .../reader/FieldReaderLocalDateTime.java | 2 +- .../fastjson2/reader/FieldReaderMapField.java | 2 +- .../reader/FieldReaderMapFieldReadOnly.java | 2 +- .../reader/FieldReaderMapMethod.java | 2 +- .../reader/FieldReaderMapMethodReadOnly.java | 2 +- .../reader/FieldReaderNumberFunc.java | 2 +- .../fastjson2/reader/ObjectReaderAdapter.java | 4 +- .../reader/ObjectReaderBaseModule.java | 3 +- .../reader/ObjectReaderImplList.java | 12 +- .../reader/ObjectReaderImplListStr.java | 1 - .../fastjson2/reader/ObjectReaderImplMap.java | 2 +- .../fastjson2/support/csv/CSVWriter.java | 4 +- .../fastjson2/support/csv/CSVWriterUTF16.java | 102 +++++----- .../fastjson2/support/csv/CSVWriterUTF8.java | 86 +++----- .../com/alibaba/fastjson2/util/BeanUtils.java | 40 ++-- .../com/alibaba/fastjson2/util/DateUtils.java | 18 +- .../alibaba/fastjson2/util/FDBigInteger.java | 3 +- .../alibaba/fastjson2/writer/FieldWriter.java | 4 +- .../fastjson2/writer/FieldWriterDate.java | 4 +- .../writer/ObjectWriterCreatorASM.java | 2 +- .../writer/ObjectWriterImplDate.java | 4 +- .../writer/ObjectWriterImplDouble.java | 4 +- .../writer/ObjectWriterImplFloat.java | 4 +- .../writer/ObjectWriterImplInstant.java | 4 +- .../writer/ObjectWriterImplInt32Array.java | 7 +- .../writer/ObjectWriterImplInt64Array.java | 4 +- .../writer/ObjectWriterImplInt8Array.java | 7 +- .../writer/ObjectWriterImplList.java | 5 +- .../fastjson2/writer/ObjectWriterImplMap.java | 3 +- .../fastjson2/support/csv/CSVWriterTest.java | 35 +++- 40 files changed, 239 insertions(+), 374 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..fcadb2cf97 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text eol=lf diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONArray.java b/core/src/main/java/com/alibaba/fastjson2/JSONArray.java index 9da34e6339..e08147ca45 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONArray.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONArray.java @@ -984,7 +984,6 @@ public byte[] toJSONBBytes(JSONWriter.Feature... features) { * @param type specify the {@link Type} to be converted * @since 2.0.4 */ - @SuppressWarnings("unchecked") public T to(Type type) { return to(type, 0L); } diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONBDump.java b/core/src/main/java/com/alibaba/fastjson2/JSONBDump.java index 916d01aa83..246e291e39 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONBDump.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONBDump.java @@ -15,7 +15,6 @@ import static com.alibaba.fastjson2.JSONB.Constants.*; import static com.alibaba.fastjson2.JSONB.typeName; import static com.alibaba.fastjson2.util.JDKUtils.*; -import static com.alibaba.fastjson2.util.JDKUtils.BIG_ENDIAN; final class JSONBDump { static Charset GB18030; diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONObject.java b/core/src/main/java/com/alibaba/fastjson2/JSONObject.java index 76d66f148f..c0740475f7 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONObject.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONObject.java @@ -23,8 +23,6 @@ import java.util.*; import java.util.function.Consumer; import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.IntStream; import static com.alibaba.fastjson2.JSONWriter.Feature.*; import static com.alibaba.fastjson2.util.BeanUtils.getAnnotations; @@ -542,31 +540,7 @@ public Long getLong(String key) { * @throws JSONException Unsupported type conversion to long value */ public long getLongValue(String key) { - Object value = super.get(key); - - if (value == null) { - return 0; - } - - if (value instanceof Number) { - return ((Number) value).longValue(); - } - - if (value instanceof String) { - String str = (String) value; - - if (str.isEmpty() || "null".equalsIgnoreCase(str)) { - return 0; - } - - if (str.indexOf('.') != -1) { - return (long) Double.parseDouble(str); - } - - return Long.parseLong(str); - } - - throw new JSONException("Can not cast '" + value.getClass() + "' to long value"); + return getLongValue(key, 0); } /** @@ -659,31 +633,7 @@ public Integer getInteger(String key) { * @throws JSONException Unsupported type conversion to int value */ public int getIntValue(String key) { - Object value = super.get(key); - - if (value == null) { - return 0; - } - - if (value instanceof Number) { - return ((Number) value).intValue(); - } - - if (value instanceof String) { - String str = (String) value; - - if (str.isEmpty() || "null".equalsIgnoreCase(str)) { - return 0; - } - - if (str.indexOf('.') != -1) { - return (int) Double.parseDouble(str); - } - - return Integer.parseInt(str); - } - - throw new JSONException("Can not cast '" + value.getClass() + "' to int value"); + return getIntValue(key, 0); } /** @@ -756,7 +706,7 @@ public Short getShort(String key) { return Short.parseShort(str); } - throw new JSONException("Can not cast '" + value.getClass() + "' to Short"); + throw new JSONException("Can not cast '" + value.getClass() + "' to short"); } /** @@ -768,27 +718,8 @@ public Short getShort(String key) { * @throws JSONException Unsupported type conversion to short value */ public short getShortValue(String key) { - Object value = super.get(key); - - if (value == null) { - return 0; - } - - if (value instanceof Number) { - return ((Number) value).shortValue(); - } - - if (value instanceof String) { - String str = (String) value; - - if (str.isEmpty() || "null".equalsIgnoreCase(str)) { - return 0; - } - - return Short.parseShort(str); - } - - throw new JSONException("Can not cast '" + value.getClass() + "' to short value"); + Short value = getShort(key); + return value == null ? 0 : value; } /** @@ -820,7 +751,7 @@ public Byte getByte(String key) { return Byte.parseByte(str); } - throw new JSONException("Can not cast '" + value.getClass() + "' to Byte"); + throw new JSONException("Can not cast '" + value.getClass() + "' to byte"); } /** @@ -832,27 +763,8 @@ public Byte getByte(String key) { * @throws JSONException Unsupported type conversion to byte value */ public byte getByteValue(String key) { - Object value = super.get(key); - - if (value == null) { - return 0; - } - - if (value instanceof Number) { - return ((Number) value).byteValue(); - } - - if (value instanceof String) { - String str = (String) value; - - if (str.isEmpty() || "null".equalsIgnoreCase(str)) { - return 0; - } - - return Byte.parseByte(str); - } - - throw new JSONException("Can not cast '" + value.getClass() + "' to byte value"); + Byte value = getByte(key); + return value == null ? 0 : value; } public byte[] getBytes(String key) { @@ -903,7 +815,7 @@ public Boolean getBoolean(String key) { return "true".equalsIgnoreCase(str) || "1".equals(str); } - throw new JSONException("Can not cast '" + value.getClass() + "' to Boolean"); + throw new JSONException("Can not cast '" + value.getClass() + "' to boolean"); } /** @@ -914,26 +826,8 @@ public Boolean getBoolean(String key) { * @throws JSONException Unsupported type conversion to boolean value */ public boolean getBooleanValue(String key) { - Object value = super.get(key); - - if (value == null) { - return false; - } - - if (value instanceof Boolean) { - return (Boolean) value; - } - - if (value instanceof Number) { - return ((Number) value).intValue() == 1; - } - - if (value instanceof String) { - String str = (String) value; - return "true".equalsIgnoreCase(str) || "1".equals(str); - } - - throw new JSONException("Can not cast '" + value.getClass() + "' to boolean value"); + Boolean value = getBoolean(key); + return value != null && value; } /** @@ -945,26 +839,8 @@ public boolean getBooleanValue(String key) { * @throws JSONException Unsupported type conversion to boolean value */ public boolean getBooleanValue(String key, boolean defaultValue) { - Object value = super.get(key); - - if (value == null) { - return defaultValue; - } - - if (value instanceof Boolean) { - return (Boolean) value; - } - - if (value instanceof Number) { - return ((Number) value).intValue() == 1; - } - - if (value instanceof String) { - String str = (String) value; - return "true".equalsIgnoreCase(str) || "1".equals(str); - } - - throw new JSONException("Can not cast '" + value.getClass() + "' to boolean value"); + Boolean value = getBoolean(key); + return value == null ? defaultValue : value; } /** @@ -2075,29 +1951,35 @@ public static JSONObject of( * @param kvArray key-value * @since 2.0.53 */ - private static JSONObject of(JSONObject object, Object... kvArray) { - if (kvArray == null || kvArray.length <= 0) { + private static JSONObject of(JSONObject jsonObject, Object... kvArray) { + if (kvArray == null || kvArray.length == 0) { throw new JSONException("The kvArray cannot be empty"); } - int kvArrayLength = kvArray.length; + final int kvArrayLength = kvArray.length; if ((kvArrayLength & 1) == 1) { throw new JSONException("The length of kvArray cannot be odd"); } - List keyList = IntStream.range(0, kvArrayLength).filter(i -> i % 2 == 0).mapToObj(i -> kvArray[i]).collect(Collectors.toList()); - keyList.forEach(key -> { - if (key == null || !(key instanceof String)) { + boolean valueMaybeNull = false; + for (int i = 0; i < kvArrayLength; i++) { + Object keyObj = kvArray[i++]; + if (!(keyObj instanceof String)) { throw new JSONException("The value corresponding to the even bit index of kvArray is key, which cannot be null and must be of type string"); } - }); - List distinctKeyList = keyList.stream().distinct().collect(Collectors.toList()); - if (keyList.size() != distinctKeyList.size()) { - throw new JSONException("The value corresponding to the even bit index of kvArray is key and cannot be duplicated"); - } - List valueList = IntStream.range(0, kvArrayLength).filter(i -> i % 2 != 0).mapToObj(i -> kvArray[i]).collect(Collectors.toList()); - for (int i = 0; i < keyList.size(); i++) { - object.put(keyList.get(i).toString(), valueList.get(i)); + String key = (String) keyObj; + if (valueMaybeNull) { + if (jsonObject.containsKey(key)) { + throw new JSONException("The value corresponding to the even bit index of kvArray is key and cannot be duplicated"); + } + jsonObject.put(key, kvArray[i]); + } else { + Object old = jsonObject.put(key, kvArray[i]); + if (old != null) { + throw new JSONException("The value corresponding to the even bit index of kvArray is key and cannot be duplicated"); + } + valueMaybeNull = kvArray[i] == null; + } } - return object; + return jsonObject; } /** diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONPathFunction.java b/core/src/main/java/com/alibaba/fastjson2/JSONPathFunction.java index 091cb3f8df..54fe2e0ab4 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONPathFunction.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONPathFunction.java @@ -603,10 +603,7 @@ public Object apply(Object o) { } if (o.getClass().isArray()) { - int len = Array.getLength(o); - for (int i = 0; i < len; i++) { - return Array.get(o, i); - } + return Array.get(o, index); } return null; diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONReader.java b/core/src/main/java/com/alibaba/fastjson2/JSONReader.java index dd570146c4..35a1ec3487 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONReader.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONReader.java @@ -656,7 +656,7 @@ public final String readFieldNameUnquote() { } readFieldNameHashCodeUnquote(); String name = getFieldName(); - if (name == null || name.equals("")) { + if (name == null || name.isEmpty()) { throw new JSONException(info("illegal input")); } return name; @@ -899,6 +899,9 @@ public final long getInt64Value() { } return number.longValue(); case JSON_TYPE_DEC: + case JSON_TYPE_INT64: + case JSON_TYPE_FLOAT: + case JSON_TYPE_DOUBLE: return getNumber().longValue(); case JSON_TYPE_BOOL: return boolValue ? 1 : 0; @@ -916,11 +919,6 @@ public final long getInt64Value() { case JSON_TYPE_ARRAY: { return toInt((List) complex); } - case JSON_TYPE_INT64: - case JSON_TYPE_FLOAT: - case JSON_TYPE_DOUBLE: - return getNumber() - .longValue(); case JSON_TYPE_BIG_DEC: try { return getBigDecimal() @@ -1829,7 +1827,7 @@ public Character readCharacter() { wasNull = true; return '\0'; } - return Character.valueOf(str.charAt(0)); + return str.charAt(0); } public abstract void readNull(); @@ -2823,7 +2821,7 @@ public final Number getNumber() { } if ((context.features & Feature.UseLongForInts.mask) != 0) { - return Long.valueOf(intValue); + return (long) intValue; } if (valueType == JSON_TYPE_INT64) { @@ -4661,7 +4659,7 @@ static JSONException numberError(int offset, int ch) { } JSONException numberError() { - return new JSONException("illegal number, offset " + offset + ", char " + (char) ch); + return new JSONException("illegal number, offset " + offset + ", char " + ch); } public final String info() { diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java b/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java index 9f49b67b2e..99019dad20 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java @@ -1015,7 +1015,7 @@ public final long readFieldNameHashCodeUnquote() { for (int i = 0; ; ++i) { if (ch == '\\') { nameEscape = true; - ch = (char) chars[offset++]; + ch = chars[offset++]; switch (ch) { case 'u': { ch = char4(chars[offset], chars[offset + 1], chars[offset + 2], chars[offset + 3]); @@ -3279,7 +3279,7 @@ private void skipString() { ch = chars[offset]; } offset++; - } else if (ch != EOI && ch != '}' && ch != ']' && ch != EOI) { + } else if (ch != '}' && ch != ']' && ch != EOI) { throw error(offset, ch); } @@ -4165,7 +4165,7 @@ public final Date readNullOrNewDate() { Date date = null; final char[] chars = this.chars; int offset = this.offset; - char ch = this.ch; + char ch; if (offset + 2 < end && chars[offset] == 'u' && chars[offset + 1] == 'l' @@ -4317,7 +4317,7 @@ public final BigDecimal readBigDecimal() { ch = chars[offset++]; if (ch == quote) { - this.ch = offset == end ? EOI : (char) chars[offset++]; + this.ch = offset == end ? EOI : chars[offset++]; this.offset = offset; nextIfComma(); return null; diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java b/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java index 33f8a93936..8dc73cb644 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java @@ -734,11 +734,10 @@ public long readFieldNameHashCodeUnquote() { int c1 = (ch & 0x3ff) + '\uDC00'; // Character.lowSurrogate(uc); hashCode ^= c1; - hashCode *= Fnv.MAGIC_PRIME; } else { hashCode ^= ch; - hashCode *= Fnv.MAGIC_PRIME; } + hashCode *= Fnv.MAGIC_PRIME; ch = offset == end ? EOI : bytes[offset++]; } @@ -5836,7 +5835,7 @@ public final boolean isNull() { @Override public final Date readNullOrNewDate() { final byte[] bytes = this.bytes; - int ch = this.ch; + int ch; int offset = this.offset; Date date = null; @@ -5938,7 +5937,7 @@ public final boolean nextIfNull() { public final void readNull() { final byte[] bytes = this.bytes; int offset = this.offset; - int ch = this.ch; + int ch; if (bytes[offset] == 'u' && bytes[offset + 1] == 'l' && bytes[offset + 2] == 'l') { diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONWriterJSONB.java b/core/src/main/java/com/alibaba/fastjson2/JSONWriterJSONB.java index 9a94332f5b..9446c79523 100644 --- a/core/src/main/java/com/alibaba/fastjson2/JSONWriterJSONB.java +++ b/core/src/main/java/com/alibaba/fastjson2/JSONWriterJSONB.java @@ -1621,14 +1621,11 @@ public void writeInt8(byte[] values) { } final byte[] bytes = this.bytes; - for (int i = 0; i < values.length; i++) { - int val = values[i]; - if (val >= BC_INT32_NUM_MIN && val <= BC_INT32_NUM_MAX) { - bytes[off++] = (byte) val; - } else { + for (int val : values) { + if (val < BC_INT32_NUM_MIN || val > BC_INT32_NUM_MAX) { bytes[off++] = (byte) (BC_INT32_BYTE_ZERO + (val >> 8)); - bytes[off++] = (byte) (val); } + bytes[off++] = (byte) val; } this.off = off; } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReader.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReader.java index 8939aa58be..ef93360027 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReader.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReader.java @@ -613,9 +613,6 @@ private String getActualFieldName(FieldReader fieldReader) { } private boolean needCompareToActualFieldClass(Class clazz) { - if (clazz.isEnum() || clazz.isInterface()) { - return true; - } - return false; + return clazz.isEnum() || clazz.isInterface(); } } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderLocalDateTime.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderLocalDateTime.java index 9308271971..070c42e721 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderLocalDateTime.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderLocalDateTime.java @@ -59,7 +59,7 @@ public boolean supportAcceptType(Class valueClass) { @Override public void readFieldValue(JSONReader jsonReader, Object object) { // 若使用的是JSONReaderJSONB则使用JSONReaderJSONB定义的时间反序列化方法 - LocalDateTime date = null; + LocalDateTime date; if (jsonReader.jsonb) { date = (LocalDateTime) dateReader.readJSONBObject(jsonReader, fieldType, fieldName, features); } else { diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapField.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapField.java index 637c4478f8..166f61f0ae 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapField.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapField.java @@ -68,7 +68,7 @@ public void readFieldValue(JSONReader jsonReader, T object) { array, arrayToMapKey, namingStrategy, - JSONFactory.getObjectReader(valueType, this.features | features), + JSONFactory.getObjectReader(valueType, features), arrayToMapDuplicateHandler); accept(object, map); return; diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapFieldReadOnly.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapFieldReadOnly.java index 21192ff535..1075b747d6 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapFieldReadOnly.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapFieldReadOnly.java @@ -133,7 +133,7 @@ public void readFieldValue(JSONReader jsonReader, T object) { array, arrayToMapKey, namingStrategy, - JSONFactory.getObjectReader(valueType, this.features | features), + JSONFactory.getObjectReader(valueType, features), arrayToMapDuplicateHandler); return; } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapMethod.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapMethod.java index f3f55a34b3..fa8daedc3d 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapMethod.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapMethod.java @@ -70,7 +70,7 @@ public void readFieldValue(JSONReader jsonReader, T object) { array, arrayToMapKey, namingStrategy, - JSONFactory.getObjectReader(valueType, this.features | features), + JSONFactory.getObjectReader(valueType, features), arrayToMapDuplicateHandler); accept(object, map); return; diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapMethodReadOnly.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapMethodReadOnly.java index 09ba3ee3a7..447dc7ee74 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapMethodReadOnly.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderMapMethodReadOnly.java @@ -118,7 +118,7 @@ public void readFieldValue(JSONReader jsonReader, T object) { array, arrayToMapKey, namingStrategy, - JSONFactory.getObjectReader(valueType, this.features | features), + JSONFactory.getObjectReader(valueType, features), arrayToMapDuplicateHandler); return; } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderNumberFunc.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderNumberFunc.java index 25a4373f10..92c9a7efc9 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderNumberFunc.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderNumberFunc.java @@ -34,7 +34,7 @@ public void accept(T object, Object value) { } if (value instanceof Boolean) { - value = ((Boolean) value).booleanValue() ? 1 : 0; + value = (Boolean) value ? 1 : 0; } function.accept(object, (V) value); diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderAdapter.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderAdapter.java index 63c1ac8d38..d38bf864b6 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderAdapter.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderAdapter.java @@ -436,7 +436,7 @@ protected final FieldReader getFieldReaderUL(long hashCode, JSONReader jsonReade if (fieldReader == null && jsonReader.isSupportSmartMatch(this.features | features)) { long hashCodeL = jsonReader.getNameHashCodeLCase(); - fieldReader = getFieldReaderLCase(hashCodeL == hashCode ? hashCode : hashCodeL); + fieldReader = getFieldReaderLCase(hashCodeL); } return fieldReader; } @@ -446,7 +446,7 @@ protected final void readFieldValue(long hashCode, JSONReader jsonReader, long f if (fieldReader == null && jsonReader.isSupportSmartMatch(this.features | features)) { long hashCodeL = jsonReader.getNameHashCodeLCase(); - fieldReader = getFieldReaderLCase(hashCodeL == hashCode ? hashCode : hashCodeL); + fieldReader = getFieldReaderLCase(hashCodeL); } if (fieldReader != null) { diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderBaseModule.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderBaseModule.java index 1c1bbbe894..639dc1e73d 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderBaseModule.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderBaseModule.java @@ -562,8 +562,7 @@ void getBeanInfo1x(BeanInfo beanInfo, Annotation annotation) { }); } - private void processBuilder(BeanInfo beanInfo, Class result) { - Class builderClass = result; + private void processBuilder(BeanInfo beanInfo, Class builderClass) { if (builderClass != void.class && builderClass != Void.class) { beanInfo.builder = builderClass; diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplList.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplList.java index 78776618ce..ee01e1825e 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplList.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplList.java @@ -46,7 +46,7 @@ public final class ObjectReaderImplList volatile Constructor constructor; public static ObjectReader of(Type type, Class listClass, long features) { - if (listClass == type && "".equals(listClass.getSimpleName())) { + if (listClass == type && listClass.getSimpleName().isEmpty()) { type = listClass.getGenericSuperclass(); listClass = listClass.getSuperclass(); } @@ -149,6 +149,8 @@ public static ObjectReader of(Type type, Class listClass, long features) { builder = GuavaSupport.immutableSetConverter(); break; case "com.google.common.collect.Lists$TransformingRandomAccessList": + case "java.util.RandomAccessSubList": + case "java.util.AbstractList$RandomAccessSubList": instanceClass = ArrayList.class; break; case "com.google.common.collect.Lists.TransformingSequentialList": @@ -174,10 +176,6 @@ public static ObjectReader of(Type type, Class listClass, long features) { instanceClass = TreeSet.class; builder = (Function) Collections::synchronizedNavigableSet; break; - case "java.util.RandomAccessSubList": - case "java.util.AbstractList$RandomAccessSubList": - instanceClass = ArrayList.class; - break; default: instanceClass = listClass; } @@ -524,10 +522,10 @@ public Object readJSONBObject(JSONReader jsonReader, Type fieldType, Object fiel } else if (listType != null && listType != this.listType) { switch (listType.getName()) { case "kotlin.collections.EmptySet": - list = (Collection) getKotlinEmptySet(listType); + list = getKotlinEmptySet(listType); break; case "kotlin.collections.EmptyList": - list = (Collection) getKotlinEmptyList(listType); + list = getKotlinEmptyList(listType); break; default: try { diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplListStr.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplListStr.java index 90c7b8296f..7834041802 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplListStr.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplListStr.java @@ -16,7 +16,6 @@ public final class ObjectReaderImplListStr implements ObjectReader { final Class listType; final Class instanceType; - Object listSingleton; public ObjectReaderImplListStr(Class listType, Class instanceType) { this.listType = listType; diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplMap.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplMap.java index de4f844aa5..9e928fcb06 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplMap.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderImplMap.java @@ -44,7 +44,7 @@ public static ObjectReader of(Type fieldType, Class mapType, long features) { Function builder = null; Class instanceType = mapType; - if ("".equals(instanceType.getSimpleName())) { + if (instanceType.getSimpleName().isEmpty()) { instanceType = mapType.getSuperclass(); if (fieldType == null) { fieldType = mapType.getGenericSuperclass(); diff --git a/core/src/main/java/com/alibaba/fastjson2/support/csv/CSVWriter.java b/core/src/main/java/com/alibaba/fastjson2/support/csv/CSVWriter.java index cdccdb3c45..cc2fde841f 100644 --- a/core/src/main/java/com/alibaba/fastjson2/support/csv/CSVWriter.java +++ b/core/src/main/java/com/alibaba/fastjson2/support/csv/CSVWriter.java @@ -237,8 +237,8 @@ public final void writeDate(long millis) { } long localSecond = epochSecond + offsetTotalSeconds; - long localEpochDay = Math.floorDiv(localSecond, (long) SECONDS_PER_DAY); - int secsOfDay = (int) Math.floorMod(localSecond, (long) SECONDS_PER_DAY); + long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY); + int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY); int year, month, dayOfMonth; { final int DAYS_PER_CYCLE = 146097; diff --git a/core/src/main/java/com/alibaba/fastjson2/support/csv/CSVWriterUTF16.java b/core/src/main/java/com/alibaba/fastjson2/support/csv/CSVWriterUTF16.java index b715877b73..08cf5dd7ea 100644 --- a/core/src/main/java/com/alibaba/fastjson2/support/csv/CSVWriterUTF16.java +++ b/core/src/main/java/com/alibaba/fastjson2/support/csv/CSVWriterUTF16.java @@ -43,23 +43,17 @@ void writeDirect(char[] bytes, int off, int len) { } public void writeComma() { - if (off + 1 == chars.length) { - flush(); - } + checkCapacity(1); chars[off++] = ','; } protected void writeQuote() { - if (off + 1 == chars.length) { - flush(); - } + checkCapacity(1); chars[off++] = '"'; } public void writeLine() { - if (off + 1 == chars.length) { - flush(); - } + checkCapacity(1); chars[off++] = '\n'; } @@ -69,19 +63,12 @@ public void writeBoolean(boolean booleanValue) { } public void writeInt64(long longValue) { - int minCapacity = off + 21; - if (minCapacity - this.chars.length > 0) { - flush(); - } - + checkCapacity(20); off = IOUtils.writeInt64(chars, off, longValue); } public void writeDateYYYMMDD10(int year, int month, int dayOfMonth) { - if (off + 11 >= this.chars.length) { - flush(); - } - + checkCapacity(10); off = IOUtils.writeLocalDate(chars, off, year, month, dayOfMonth); } @@ -92,9 +79,7 @@ public void writeDateTime19( int hour, int minute, int second) { - if (off + 20 >= this.chars.length) { - flush(); - } + checkCapacity(19); final char[] chars = this.chars; int off = this.off; @@ -108,7 +93,7 @@ public void writeDateTime19( this.off = off + 9; } - public void writeString(String str) { + public void writeString(final String str) { if (str == null || str.isEmpty()) { return; } @@ -139,52 +124,60 @@ public void writeString(String str) { } if (escapeCount == 0) { - str.getChars(0, str.length(), chars, off); - off += str.length(); + if (len + off >= chars.length) { + flush(); + if (len > chars.length) { + try { + out.write(str); + } catch (IOException e) { + throw new JSONException("write csv error", e); + } + return; + } + } + str.getChars(0, len, chars, off); + off += len; return; } - if (off + 2 + str.length() + escapeCount >= chars.length) { - flush(); - } + checkCapacity(2 + len + escapeCount); + // 利用本地局部变量,可以提高遍历速度 + final char[] chars = this.chars; + final int max = chars.length - 2; + int off = this.off; chars[off++] = '"'; - for (int i = 0; i < str.length(); i++) { - char ch = str.charAt(i); + for (int i = 0; i < len; ) { + char ch = str.charAt(i++); if (ch == '"') { chars[off++] = '"'; chars[off++] = '"'; } else { chars[off++] = ch; } + if (off >= max) { + flush(); + off = this.off; + } } chars[off++] = '"'; + this.off = off; } public void writeInt32(int intValue) { - int minCapacity = off + 11; - if (minCapacity - this.chars.length > 0) { - flush(); - } - + checkCapacity(11); off = IOUtils.writeInt32(chars, off, intValue); } public void writeDouble(double value) { - int minCapacity = off + 24; - if (minCapacity - this.chars.length > 0) { - flush(); - } + checkCapacity(24); int size = DoubleToDecimal.toString(value, this.chars, off, true); off += size; } public void writeFloat(float value) { - int minCapacity = off + 15; - if (minCapacity - this.chars.length > 0) { - flush(); - } + checkCapacity(15); int size = DoubleToDecimal.toString(value, this.chars, off, true); off += size; @@ -205,7 +198,7 @@ public void writeString(byte[] utf8) { return; } - String str = new String(utf8, 0, utf8.length, StandardCharsets.UTF_8); + String str = new String(utf8, StandardCharsets.UTF_8); writeString(str); } @@ -217,10 +210,7 @@ public void writeDecimal(BigDecimal value) { String str = value.toString(); int strlen = str.length(); - int minCapacity = off + 24; - if (minCapacity - this.chars.length > 0) { - flush(); - } + checkCapacity(24); str.getChars(0, strlen, chars, off); off += strlen; @@ -237,10 +227,7 @@ public void writeDecimal(long unscaledVal, int scale) { return; } - int minCapacity = off + 24; - if (minCapacity - this.chars.length > 0) { - flush(); - } + checkCapacity(24); off = IOUtils.writeDecimal(chars, off, unscaledVal, scale); } @@ -265,6 +252,9 @@ public void writeLocalDateTime(LocalDateTime ldt) { return; } + // "yyyy-MM-dd HH:mm:ss" + checkCapacity(19); + off = IOUtils.writeLocalDate(chars, off, ldt.getYear(), ldt.getMonthValue(), ldt.getDayOfMonth()); chars[off++] = ' '; off = IOUtils.writeLocalTime(chars, off, ldt.toLocalTime()); @@ -274,14 +264,18 @@ protected void writeRaw(String str) { if (str == null || str.isEmpty()) { return; } + checkCapacity(str.length()); - if (str.length() + off >= chars.length) { - flush(); - } str.getChars(0, str.length(), this.chars, off); off += str.length(); } + void checkCapacity(int incr) { + if (off + incr >= chars.length) { + flush(); + } + } + @Override public void close() throws IOException { if (off > 0) { diff --git a/core/src/main/java/com/alibaba/fastjson2/support/csv/CSVWriterUTF8.java b/core/src/main/java/com/alibaba/fastjson2/support/csv/CSVWriterUTF8.java index 88de07c319..367103dcd1 100644 --- a/core/src/main/java/com/alibaba/fastjson2/support/csv/CSVWriterUTF8.java +++ b/core/src/main/java/com/alibaba/fastjson2/support/csv/CSVWriterUTF8.java @@ -46,23 +46,17 @@ void writeDirect(byte[] bytes, int off, int len) { } public void writeComma() { - if (off + 1 == bytes.length) { - flush(); - } + checkCapacity(1); bytes[off++] = ','; } protected void writeQuote() { - if (off + 1 == bytes.length) { - flush(); - } + checkCapacity(1); bytes[off++] = '"'; } public void writeLine() { - if (off + 1 == bytes.length) { - flush(); - } + checkCapacity(1); bytes[off++] = '\n'; } @@ -72,18 +66,13 @@ public void writeBoolean(boolean booleanValue) { } public void writeInt64(long longValue) { - int minCapacity = off + 21; - if (minCapacity - this.bytes.length > 0) { - flush(); - } + checkCapacity(20); // -9223372036854775808 off = IOUtils.writeInt64(bytes, off, longValue); } public void writeDateYYYMMDD10(int year, int month, int dayOfMonth) { - if (off + 11 >= this.bytes.length) { - flush(); - } + checkCapacity(10); off = IOUtils.writeLocalDate(bytes, off, year, month, dayOfMonth); } @@ -96,9 +85,7 @@ public void writeDateTime19( int minute, int second ) { - if (off + 20 >= this.bytes.length) { - flush(); - } + checkCapacity(19); final byte[] bytes = this.bytes; int off = this.off; @@ -125,29 +112,20 @@ public void writeString(String value) { } public void writeInt32(int intValue) { - int minCapacity = off + 11; - if (minCapacity - this.bytes.length > 0) { - flush(); - } + checkCapacity(11); // -2147483648 off = IOUtils.writeInt32(bytes, off, intValue); } public void writeDouble(double value) { - int minCapacity = off + 24; - if (minCapacity - this.bytes.length > 0) { - flush(); - } + checkCapacity(24); int size = DoubleToDecimal.toString(value, this.bytes, off, true); off += size; } public void writeFloat(float value) { - int minCapacity = off + 15; - if (minCapacity - this.bytes.length > 0) { - flush(); - } + checkCapacity(15); int size = DoubleToDecimal.toString(value, this.bytes, off, true); off += size; @@ -196,9 +174,12 @@ public void writeString(byte[] utf8) { return; } - if (off + 2 + utf8.length + escapeCount >= bytes.length) { - flush(); - } + checkCapacity(2 + len + escapeCount); + + // 利用本地局部变量,可以提高遍历速度 + final byte[] bytes = this.bytes; + final int max = bytes.length - 2; + int off = this.off; bytes[off++] = '"'; for (byte ch : utf8) { @@ -208,8 +189,13 @@ public void writeString(byte[] utf8) { } else { bytes[off++] = ch; } + if (off >= max) { + flush(); + off = this.off; + } } bytes[off++] = '"'; + this.off = off; } public void writeDecimal(BigDecimal value) { @@ -220,10 +206,7 @@ public void writeDecimal(BigDecimal value) { String str = value.toString(); int strlen = str.length(); - int minCapacity = off + 24; - if (minCapacity - this.bytes.length > 0) { - flush(); - } + checkCapacity(24); str.getBytes(0, strlen, bytes, off); off += strlen; @@ -240,10 +223,7 @@ public void writeDecimal(long unscaledVal, int scale) { return; } - int minCapacity = off + 24; - if (minCapacity - this.bytes.length > 0) { - flush(); - } + checkCapacity(24); off = IOUtils.writeDecimal(bytes, off, unscaledVal, scale); } @@ -269,18 +249,7 @@ protected void writeRaw(String str) { } byte[] strBytes = str.getBytes(charset); - if (strBytes.length + off < bytes.length) { - System.arraycopy(strBytes, 0, bytes, off, strBytes.length); - off += strBytes.length; - } else { - flush(); - if (strBytes.length >= bytes.length) { - writeDirect(strBytes, 0, strBytes.length); - } else { - System.arraycopy(strBytes, 0, bytes, off, strBytes.length); - off += strBytes.length; - } - } + writeRaw(strBytes); } public void writeLocalDateTime(LocalDateTime ldt) { @@ -288,11 +257,20 @@ public void writeLocalDateTime(LocalDateTime ldt) { return; } + // "yyyy-MM-dd HH:mm:ss" + checkCapacity(19); + off = IOUtils.writeLocalDate(bytes, off, ldt.getYear(), ldt.getMonthValue(), ldt.getDayOfMonth()); bytes[off++] = ' '; off = IOUtils.writeLocalTime(bytes, off, ldt.toLocalTime()); } + void checkCapacity(int incr) { + if (off + incr >= bytes.length) { + flush(); + } + } + @Override public void close() throws IOException { if (off > 0) { diff --git a/core/src/main/java/com/alibaba/fastjson2/util/BeanUtils.java b/core/src/main/java/com/alibaba/fastjson2/util/BeanUtils.java index 0abb287a28..796e334029 100644 --- a/core/src/main/java/com/alibaba/fastjson2/util/BeanUtils.java +++ b/core/src/main/java/com/alibaba/fastjson2/util/BeanUtils.java @@ -2828,23 +2828,27 @@ public static void processJacksonJsonFormat(BeanInfo beanInfo, Annotation annota String name = m.getName(); try { Object result = m.invoke(annotation); - if ("pattern".equals(name)) { - String pattern = (String) result; - if (!pattern.isEmpty()) { - beanInfo.format = pattern; - } - } else if ("shape".equals(name)) { - String shape = ((Enum) result).name(); - if ("NUMBER".equals(shape)) { - beanInfo.format = "millis"; - } else if ("OBJECT".equals(shape)) { - beanInfo.writeEnumAsJavaBean = true; - } - } else if ("locale".equals(name)) { - String locale = (String) result; - if (!locale.isEmpty() && !"##default".equals(locale)) { - beanInfo.locale = Locale.forLanguageTag(locale); - } + switch (name) { + case "pattern": + String pattern = (String) result; + if (!pattern.isEmpty()) { + beanInfo.format = pattern; + } + break; + case "shape": + String shape = ((Enum) result).name(); + if ("NUMBER".equals(shape)) { + beanInfo.format = "millis"; + } else if ("OBJECT".equals(shape)) { + beanInfo.writeEnumAsJavaBean = true; + } + break; + case "locale": + String locale = (String) result; + if (!locale.isEmpty() && !"##default".equals(locale)) { + beanInfo.locale = Locale.forLanguageTag(locale); + } + break; } } catch (Throwable ignored) { // ignored @@ -3003,7 +3007,7 @@ public static boolean isExtendedMap(Class objectClass) { if (objectClass == HashMap.class || objectClass == LinkedHashMap.class || objectClass == TreeMap.class - || "".equals(objectClass.getSimpleName()) + || objectClass.getSimpleName().isEmpty() ) { return false; } diff --git a/core/src/main/java/com/alibaba/fastjson2/util/DateUtils.java b/core/src/main/java/com/alibaba/fastjson2/util/DateUtils.java index 9ad1ad9b65..7fa56e0c85 100644 --- a/core/src/main/java/com/alibaba/fastjson2/util/DateUtils.java +++ b/core/src/main/java/com/alibaba/fastjson2/util/DateUtils.java @@ -53,7 +53,7 @@ public class DateUtils { } long localSecond = epochSecond + offsetTotalSeconds; - LOCAL_EPOCH_DAY = (int) Math.floorDiv(localSecond, (long) SECONDS_PER_DAY); + LOCAL_EPOCH_DAY = (int) Math.floorDiv(localSecond, SECONDS_PER_DAY); } static class CacheDate8 { @@ -10939,8 +10939,8 @@ public static String formatYMDHMS19(Date date, ZoneId zoneId) { } long localSecond = epochSecond + offsetTotalSeconds; - long localEpochDay = Math.floorDiv(localSecond, (long) SECONDS_PER_DAY); - int secsOfDay = (int) Math.floorMod(localSecond, (long) SECONDS_PER_DAY); + long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY); + int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY); int year, month, dayOfMonth; { final int DAYS_PER_CYCLE = 146097; @@ -11045,7 +11045,7 @@ public static String formatYMD8(long timeMillis, ZoneId zoneId) { } long localSecond = epochSecond + offsetTotalSeconds; - long localEpochDay = Math.floorDiv(localSecond, (long) SECONDS_PER_DAY); + long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY); int off = (int) (localEpochDay - LOCAL_EPOCH_DAY + 128); @@ -11211,7 +11211,7 @@ public static String formatYMD10(long timeMillis, ZoneId zoneId) { } long localSecond = epochSecond + offsetTotalSeconds; - long localEpochDay = Math.floorDiv(localSecond, (long) SECONDS_PER_DAY); + long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY); int off = (int) (localEpochDay - LOCAL_EPOCH_DAY + 128); final String[] cache = CacheDate10.CACHE; @@ -11584,8 +11584,8 @@ public static String format(long timeMillis, DateTimeFormatPattern pattern) { } long localSecond = epochSecond + offsetTotalSeconds; - long localEpochDay = Math.floorDiv(localSecond, (long) SECONDS_PER_DAY); - int secsOfDay = (int) Math.floorMod(localSecond, (long) SECONDS_PER_DAY); + long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY); + int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY); int year, month, dayOfMonth; { final int DAYS_PER_CYCLE = 146097; @@ -11745,8 +11745,8 @@ public static String toString(long timeMillis, boolean timeZone, ZoneId zoneId) } long localSecond = epochSecond + offsetTotalSeconds; - long localEpochDay = Math.floorDiv(localSecond, (long) SECONDS_PER_DAY); - int secsOfDay = (int) Math.floorMod(localSecond, (long) SECONDS_PER_DAY); + long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY); + int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY); int year, month, dayOfMonth; { final int DAYS_PER_CYCLE = 146097; diff --git a/core/src/main/java/com/alibaba/fastjson2/util/FDBigInteger.java b/core/src/main/java/com/alibaba/fastjson2/util/FDBigInteger.java index 14934f279b..e90ed00ad7 100644 --- a/core/src/main/java/com/alibaba/fastjson2/util/FDBigInteger.java +++ b/core/src/main/java/com/alibaba/fastjson2/util/FDBigInteger.java @@ -267,14 +267,13 @@ public FDBigInteger leftShift(int shift) { int prev = data[idx]; int hi = prev >>> anticount; int[] result = data; - int[] src = data; if (hi != 0) { if (nWords == data.length) { this.data = result = new int[nWords + 1]; } result[nWords++] = hi; } - leftShift(src, idx, result, bitcount, anticount, prev); + leftShift(data, idx, result, bitcount, anticount, prev); } } this.nWords = nWords; diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriter.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriter.java index 1777ac763b..1371563457 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriter.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriter.java @@ -729,8 +729,8 @@ public void writeDate(JSONWriter jsonWriter, boolean writeFieldName, long millis .getOffset(instant); long localSecond = epochSecond + offset.getTotalSeconds(); - long localEpochDay = Math.floorDiv(localSecond, (long) SECONDS_PER_DAY); - int secsOfDay = (int) Math.floorMod(localSecond, (long) SECONDS_PER_DAY); + long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY); + int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY); int year, month, dayOfMonth; { final int DAYS_PER_CYCLE = 146097; diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterDate.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterDate.java index 3037e7cfda..821d9be5fb 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterDate.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterDate.java @@ -154,8 +154,8 @@ public void writeDate(JSONWriter jsonWriter, long timeMillis) { } long localSecond = epochSecond + offsetTotalSeconds; - long localEpochDay = Math.floorDiv(localSecond, (long) SECONDS_PER_DAY); - int secsOfDay = (int) Math.floorMod(localSecond, (long) SECONDS_PER_DAY); + long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY); + int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY); int year, month, dayOfMonth; { final int DAYS_PER_CYCLE = 146097; diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreatorASM.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreatorASM.java index 11e0b445aa..85ef8693c7 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreatorASM.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreatorASM.java @@ -1088,7 +1088,7 @@ private void gwListJSONB( int REF_PATH = mwc.var("REF_PATH"); boolean listSimple = false; - Type itemType = null; + Type itemType; Class itemClass = null; if (fieldType instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) fieldType; diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplDate.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplDate.java index 35398448d8..b8092cec11 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplDate.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplDate.java @@ -123,8 +123,8 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f } long localSecond = epochSecond + offsetTotalSeconds; - long localEpochDay = Math.floorDiv(localSecond, (long) SECONDS_PER_DAY); - int secsOfDay = (int) Math.floorMod(localSecond, (long) SECONDS_PER_DAY); + long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY); + int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY); int year, month, dayOfMonth; { final int DAYS_PER_CYCLE = 146097; diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplDouble.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplDouble.java index 19db92e58e..d4430b1f1f 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplDouble.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplDouble.java @@ -22,7 +22,7 @@ public void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, T return; } - double value = ((Double) object).doubleValue(); + double value = (Double) object; if ((features & JSONWriter.Feature.WriteNonStringValueAsString.mask) != 0) { jsonWriter.writeString(value); } else { @@ -51,7 +51,7 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f return; } - double value = ((Double) object).doubleValue(); + double value = (Double) object; if ((features & JSONWriter.Feature.WriteNonStringValueAsString.mask) != 0) { jsonWriter.writeString(value); return; diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplFloat.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplFloat.java index 303478daff..00491a0b6c 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplFloat.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplFloat.java @@ -22,7 +22,7 @@ public void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, T return; } - float value = ((Float) object).floatValue(); + float value = (Float) object; if ((features & JSONWriter.Feature.WriteNonStringValueAsString.mask) != 0) { jsonWriter.writeString(value); } else { @@ -43,7 +43,7 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f return; } - float value = ((Float) object).floatValue(); + float value = (Float) object; if ((features & JSONWriter.Feature.WriteNonStringValueAsString.mask) != 0) { jsonWriter.writeString(value); return; diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInstant.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInstant.java index c2558caf49..b3f00592a6 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInstant.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInstant.java @@ -54,8 +54,8 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f } long localSecond = epochSecond + offsetTotalSeconds; - long localEpochDay = Math.floorDiv(localSecond, (long) SECONDS_PER_DAY); - int secsOfDay = (int) Math.floorMod(localSecond, (long) SECONDS_PER_DAY); + long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY); + int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY); int year, month, dayOfMonth; { final int DAYS_PER_CYCLE = 146097; diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInt32Array.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInt32Array.java index 49eadd3da1..7f5e3a2f33 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInt32Array.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInt32Array.java @@ -40,7 +40,7 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f continue; } - int value = item.intValue(); + int value = item; if (writeAsString) { jsonWriter.writeString(value); } else { @@ -66,13 +66,12 @@ public void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, T Integer[] array = (Integer[]) object; jsonWriter.startArray(array.length); - for (int i = 0; i < array.length; i++) { - Integer item = array[i]; + for (Integer item : array) { if (item == null) { jsonWriter.writeNull(); continue; } - int value = item.intValue(); + int value = item; if (writeAsString) { jsonWriter.writeString(value); } else { diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInt64Array.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInt64Array.java index 090a37be52..d8b7a0b0a3 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInt64Array.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInt64Array.java @@ -42,7 +42,7 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f continue; } - long longValue = item.longValue(); + long longValue = item; if (writeAsString) { jsonWriter.writeString(longValue); } else { @@ -74,7 +74,7 @@ public void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, T continue; } - long longValue = item.longValue(); + long longValue = item; if (writeAsString) { jsonWriter.writeString(longValue); } else { diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInt8Array.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInt8Array.java index fa6dbe2f5d..2816183175 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInt8Array.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplInt8Array.java @@ -34,7 +34,7 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f if (value == null) { jsonWriter.writeNull(); } else { - byte byteValue = value.byteValue(); + byte byteValue = value; if (writeAsString) { jsonWriter.writeString(byteValue); } else { @@ -60,12 +60,11 @@ public void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, T Byte[] array = (Byte[]) object; jsonWriter.startArray(array.length); - for (int i = 0; i < array.length; i++) { - Byte value = array[i]; + for (Byte value : array) { if (value == null) { jsonWriter.writeNull(); } else { - byte byteValue = value.byteValue(); + byte byteValue = value; if (writeAsString) { jsonWriter.writeString(byteValue); } else { diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplList.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplList.java index c275fe161e..c1404fbaae 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplList.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplList.java @@ -376,9 +376,8 @@ private List getList(Object object) { } else if (object instanceof Iterable) { final Iterable items = (Iterable) object; List list = items instanceof Collection ? new ArrayList(((Collection) items).size()) : new ArrayList(); - Iterator iterator = items.iterator(); - while (iterator.hasNext()) { - list.add(iterator.next()); + for (Object item : items) { + list.add(item); } return list; } else { diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplMap.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplMap.java index 6c00234b27..9c965e675a 100644 --- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplMap.java +++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterImplMap.java @@ -619,9 +619,8 @@ public void writeWithFilter(JSONWriter jsonWriter, Object object, Object fieldNa key = entryKey.toString(); } - String refPath = null; if (refDetect) { - refPath = jsonWriter.setPath(key, value); + String refPath = jsonWriter.setPath(key, value); if (refPath != null) { jsonWriter.writeName(key); jsonWriter.writeColon(); diff --git a/core/src/test/java/com/alibaba/fastjson2/support/csv/CSVWriterTest.java b/core/src/test/java/com/alibaba/fastjson2/support/csv/CSVWriterTest.java index 21db7bbe22..73b5ae741d 100644 --- a/core/src/test/java/com/alibaba/fastjson2/support/csv/CSVWriterTest.java +++ b/core/src/test/java/com/alibaba/fastjson2/support/csv/CSVWriterTest.java @@ -3,11 +3,10 @@ import com.alibaba.fastjson2.reader.ByteArrayValueConsumer; import com.alibaba.fastjson2.reader.CharArrayValueConsumer; import com.alibaba.fastjson2.util.DateUtils; +import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Test; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.StringWriter; +import java.io.*; import java.math.BigDecimal; import java.math.BigInteger; import java.nio.charset.StandardCharsets; @@ -387,6 +386,36 @@ public void testWriteInstant1UTF8() throws Exception { } } + @Test + public void testWriteStringForIssue2848() throws IOException { + // see issue#2848 + OutputStreamWriter out = new OutputStreamWriter(new ByteArrayOutputStream(), StandardCharsets.UTF_8); + try (CSVWriter writer = CSVWriter.of(out)) { + writer.writeValue(StringUtils.repeat('1', 65534)); + writer.writeComma(); + writer.writeString("123"); // java.lang.StringIndexOutOfBoundsException: offset 65535, count 3, length 65536 + } + } + + @Test + public void testWriteLocalDateTimeForIssue2848() throws IOException { + OutputStreamWriter out = new OutputStreamWriter(new ByteArrayOutputStream(), StandardCharsets.UTF_8); + try (CSVWriter writer = CSVWriter.of(out)) { + writer.writeValue(StringUtils.repeat('1', 65534)); + writer.writeComma(); + writer.writeLocalDateTime(LocalDateTime.now()); // java.lang.ArrayIndexOutOfBoundsException: Index 65539 out of bounds for length 65536 + } + } + + @Test + public void testWriteLargeStringForIssue2848() throws IOException { + OutputStreamWriter out = new OutputStreamWriter(new ByteArrayOutputStream(), StandardCharsets.UTF_8); + try (CSVWriter writer = CSVWriter.of(out)) { + writer.writeValue(StringUtils.repeat('1', 65534)); + writer.writeComma(); + writer.writeString(StringUtils.repeat('1', 65537)); // java.lang.StringIndexOutOfBoundsException: offset 65535, count 65537, length 65536 + } + } public static class Bean { public int id; public String name;