Skip to content

Instantly share code, notes, and snippets.

@msdx
Last active November 16, 2018 08:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save msdx/326f948bb4ad9f063718e9d2cde6f6f5 to your computer and use it in GitHub Desktop.
Save msdx/326f948bb4ad9f063718e9d2cde6f6f5 to your computer and use it in GitHub Desktop.
kotlin 泛型问题
/*
* Copyright (c) 2018. Xi'an iRain IOT Technology service CO., Ltd (ShenZhen). All Rights Reserved.
*/
package com.parkingwang.iop.api.json
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import com.parkingwang.iop.api.services.park.objects.Version
import org.itishka.gsonflatten.FlattenTypeAdapterFactory
import java.util.ArrayList
/**
* GSON 库的一些类型解析的兼容处理。
*
* @author 黄浩杭 (huanghaohang@parkingwang.com)
* @since 2.12
*/
object Json {
private val BOOLEAN_AS_INT_ADAPTER = BooleanAsIntAdapter()
private val COMPAT_FLOW_ADAPTER = CompatFloatAdapter()
val GSON: Gson = GsonBuilder()
.registerTypeAdapterFactory(ValueEnumAdapterFactory())
.create()
fun <T> parseArray(json: String, cls: Class<T>): ArrayList<T>? {
val type = TypeToken.getParameterized(ArrayList::class.java, cls).type
return GSON.fromJson<ArrayList<T>>(json, type)
}
fun <T> parseObject(json: String, cls: Class<T>): T? {
return GSON.fromJson(json, cls)
}
fun <T> toJson(`object`: T): String {
return GSON.toJson(`object`)
}
}
/*
* Copyright (c) 2018. Xi'an iRain IOT Technology service CO., Ltd (ShenZhen). All Rights Reserved.
*/
package com.parkingwang.iop.api.json
/**
* @author 黄浩杭 (huanghaohang@parkingwang.com)
* @since 2018-02-06 1.13
*/
interface ValueEnum {
/**
* 返回枚举对应的数值
*
* @return 枚举值
*/
val value: Int
}
/*
* Copyright (c) 2018. Xi'an iRain IOT Technology service CO., Ltd (ShenZhen). All Rights Reserved.
*/
package com.parkingwang.iop.api.json;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
/**
* 按值解析为枚举类型
*
* @author 黄浩杭 (huanghaohang@parkingwang.com)
* @version 2.8
* @since 2018-02-06 1.13
*/
public class ValueEnumAdapter<T extends Enum<T>> extends TypeAdapter<T> {
private final T[] mConstants;
public ValueEnumAdapter(Class<T> enumType) {
mConstants = enumType.getEnumConstants();
}
@Override
public void write(JsonWriter out, T t) throws IOException {
if (t == null) {
out.value("");
} else {
out.value(String.valueOf(((ValueEnum) t).getValue()));
}
}
@Override
public T read(JsonReader in) throws IOException {
JsonToken peek = in.peek();
final int value;
switch (peek) {
case NUMBER:
value = in.nextInt();
break;
case STRING:
final String string = in.nextString();
if (string.isEmpty()) {
return null;
}
value = Integer.parseInt(string);
break;
case NULL:
return null;
default:
throw new IllegalStateException("Expected NUMBER but was " + peek + " " + in.getPath());
}
for (T constant : mConstants) {
if (((ValueEnum) constant).getValue() == value) {
return constant;
}
}
return null;
}
}
/*
* Copyright (c) 2018. Xi'an iRain IOT Technology service CO., Ltd (ShenZhen). All Rights Reserved.
*/
package com.parkingwang.iop.api.json
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter
import java.io.IOException
/**
* 按值解析为枚举类型
*
* @author 黄浩杭 (huanghaohang@parkingwang.com)
* @version 2.8
* @since 2018-02-06 1.13
*/
class ValueEnumAdapter<T : Enum<T>>(enumType: Class<T>) : TypeAdapter<T>() {
private val constants: Array<T> = enumType.enumConstants
@Throws(IOException::class)
override fun write(out: JsonWriter, t: T?) {
if (t == null) {
out.value("")
} else {
out.value((t as ValueEnum).value.toString())
}
}
@Throws(IOException::class)
override fun read(`in`: JsonReader): T? {
val peek = `in`.peek()
val value: Int
value = when (peek) {
JsonToken.NUMBER -> `in`.nextInt()
JsonToken.STRING -> {
val string = `in`.nextString()
if (string.isEmpty()) {
return null
}
Integer.parseInt(string)
}
JsonToken.NULL -> return null
else -> throw IllegalStateException("Expected NUMBER but was " + peek + " " + `in`.path)
}
for (constant in constants) {
if ((constant as ValueEnum).value == value) {
return constant
}
}
return null
}
}
/*
* Copyright (c) 2018. Xi'an iRain IOT Technology service CO., Ltd (ShenZhen). All Rights Reserved.
*/
package com.parkingwang.iop.api.json
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter
import java.io.IOException
/**
* 按值解析为枚举类型
*
* @author 黄浩杭 (huanghaohang@parkingwang.com)
* @version 2.8
* @since 2018-02-06 1.13
*/
class ValueEnumAdapter<T>(enumType: Class<T>) : TypeAdapter<T>() where T : Enum<T>, T : ValueEnum {
private val constants: Array<T> = enumType.enumConstants
@Throws(IOException::class)
override fun write(out: JsonWriter, t: T?) {
if (t == null) {
out.value("")
} else {
out.value(t.value.toString())
}
}
@Throws(IOException::class)
override fun read(`in`: JsonReader): T? {
val peek = `in`.peek()
val value: Int
value = when (peek) {
JsonToken.NUMBER -> `in`.nextInt()
JsonToken.STRING -> {
val string = `in`.nextString()
if (string.isEmpty()) {
return null
}
Integer.parseInt(string)
}
JsonToken.NULL -> return null
else -> throw IllegalStateException("Expected NUMBER but was " + peek + " " + `in`.path)
}
for (constant in constants) {
if (constant.value == value) {
return constant
}
}
return null
}
}
/*
* Copyright (c) 2018. Xi'an iRain IOT Technology service CO., Ltd (ShenZhen). All Rights Reserved.
*/
package com.parkingwang.iop.api.json;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
/**
* 值类型的枚举解析处理
*
* @author 黄浩杭 (huanghaohang@parkingwang.com)
* @since 2018-02-06 1.13
*/
public class ValueEnumAdapterFactory implements TypeAdapterFactory {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
Class<?> rawType = type.getRawType();
if (rawType.isEnum() && ValueEnum.class.isAssignableFrom(rawType)) {
return (TypeAdapter<T>) new ValueEnumAdapter<>((Class<? extends Enum>)rawType);
}
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment