TypeAdapterFactory的Lambda表达式

时间:2019-03-13 22:01:56

标签: java lambda gson

我正在尝试使用lambda表达式来简化以下代码片段。详细信息可以在这里找到:Could not serialize object cause of HibernateProxy

public class HibernateProxyTypeAdapter extends TypeAdapter<HibernateProxy> {
    public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
        @Override
        @SuppressWarnings("unchecked")
        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
            return (HibernateProxy.class.isAssignableFrom(type.getRawType())
                    ? (TypeAdapter<T>) new HibernateProxyTypeAdapter(gson)
                    : null);
        }
    };
    ...
    ...
    ...
}

我将代码更改为此:

public static final TypeAdapterFactory FACTORY = (gson, type) -> HibernateProxy.class.isAssignableFrom(type.getRawType())
                    ? (TypeAdapter<T>) new HibernateProxyTypeAdapter(gson)
                    : null;

但是我在Eclispe中遇到错误:Illegal lambda expression: Method create of type TypeAdapterFactory is generic

我也尝试过这个,但是抛出了同样的错误。

public static final TypeAdapterFactory FACTORY = (gson, type) -> HibernateProxy.class.isAssignableFrom(type.getRawType())
                    ? (TypeAdapter<Hibernate>) new HibernateProxyTypeAdapter(gson)
                    : null;

在这种情况下可以使用lambda表达式吗?我应该如何修改我的代码?

1 个答案:

答案 0 :(得分:0)

我不认为它可以被“简化”,而是更加复杂。错误的原因是该方法是通用的,您必须使用通用(功能性)接口,如下所示:

@SuppressWarnings("rawtypes")
private static final BiFunction<Gson, TypeToken, TypeAdapter> GENERIC_FACTORY = (gson, typeToken)
        -> HibernateProxy.class.isAssignableFrom(typeToken.getRawType()) ? new HibernateTypeAdapter(gson) : null;

static final TypeAdapterFactory FACTORY = GENERIC_FACTORY::apply;

好吧,马马虎虎吧?如果内联,则更加难看:

static final TypeAdapterFactory FACTORY = ((BiFunction<Gson, TypeToken, TypeAdapter>) (gson, typeToken)
        -> HibernateProxy.class.isAssignableFrom(typeToken.getRawType()) ? new HibernateTypeAdapter(gson) : null)::apply;

如果您真的认为lambda表达式是在这种情况下所需的,则有两种方法:

通用类型适配器工厂适配器

@FunctionalInterface
public interface GenericTypeAdapterFactory
        extends TypeAdapterFactory {

    TypeAdapter<?> createUnchecked(Gson gson, TypeToken<?> typeToken);

    @Override
    default <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
        @SuppressWarnings("unchecked")
        final TypeAdapter<T> castTypeAdapter = (TypeAdapter<T>) createUnchecked(gson, typeToken);
        return castTypeAdapter;
    }

}

使用

static final TypeAdapterFactory FACTORY = (GenericTypeAdapterFactory) (gson, typeToken)
        -> HibernateProxy.class.isAssignableFrom(typeToken.getRawType()) ? new HibernateTypeAdapter(gson) : null;

通用包装器

interface GsonTypeAdapterFactory<T>
        extends BiFunction<Gson, TypeToken<T>, TypeAdapter<T>> {
}

static <TF> TypeAdapterFactory wrap(final GsonTypeAdapterFactory<TF> factory) {
    return new TypeAdapterFactory() {
        @Override
        public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
            @SuppressWarnings("unchecked")
            final TypeToken<TF> castTypeToken = (TypeToken<TF>) typeToken;
            @SuppressWarnings("unchecked")
            final TypeAdapter<T> castTypeAdapter = (TypeAdapter<T>) factory.apply(gson, castTypeToken);
            return castTypeAdapter;
        }
    };
}

使用

static final TypeAdapterFactory FACTORY = GenericTypeAdapterFactory.wrap((GenericTypeAdapterFactory.GsonTypeAdapterFactory<HibernateProxy>) (gson, typeToken)
        -> HibernateProxy.class.isAssignableFrom(typeToken.getRawType()) ? new HibernateTypeAdapter(gson) : null
);

至少有3-4种解决方法,我不推荐其中任何一种,但请坚持使用您的初始方法。