将泛型参数传递给类的方法或将方法的结果转换为给定的泛型类型?

时间:2018-10-22 18:46:21

标签: java generics type-erasure

我需要从一种方法返回结果,该方法返回的对象本身应具有与Generics参数相同的类型。这似乎比我想象的要难。

这是一个简化的示例:

import android.content.Context;

public class PreferencesManager<T>
{
    private EncryptingPreferencesManager<T> encryptingPreferencesManager;

    public PreferencesManager(Context context)
    {
        encryptingPreferencesManager = new EncryptingPreferencesManager<>(context);
    }

    public T getPreferencesData(String identifier)
    {
        T data = encryptingPreferencesManager.getData(identifier);

    return data;
    }
}

...以及实例化的类:

public class EncryptingPreferencesManager<T>
{
    private Context context;

    public EncryptingPreferencesManager(Context context)
    {
        this.context = context;
    }

    @SuppressWarnings("unchecked")
    public T getData(String identifier) throws GeneralSecurityException, IOException
    {
    //do some stuff and get the content, which is a JSON 

        final T result = (T)JsonMapper.fromJsonToJavaObject(decryptedJson, ??????.class);

        return result;
    }
}

这是JsonMapper方法:

public static Object fromJsonToJavaObject(String jsonObject, Class<?> clazz) throws JsonParseException, JsonMappingException, IOException
{
    return objectMapper.readValue(jsonObject, clazz);
}

不应更改Json映射器方法。它基本上可以工作。不能正常工作的是中间带有 ??????。class 部分的类。

如果我在这里传递诸如 CorrectResultObject.class 之类的类定义,则getData(...)将返回CorrectResultObject的实例,因此可以正常工作。但这必须是通用的。由于我无法传递 T.class 之类的东西,因此我考虑传递 Object.class ,但是最终结果(如上所示,在投射之后)突然是LinkedHashMap吗? !我不明白 T 的类型信息是如何丢失的,因为类本身是用T实例化的,而类型擦除仅发生在转换时的方法中,而不发生在实例化的类中?! / p>

如何编写类以实现 getData(...)返回正确的泛型类型的实例?

2 个答案:

答案 0 :(得分:1)

您可以修改getData方法并将Class对象传递给它,以返回相同类的对象。
像这样:

public T getData(String identifier, Class<? extends T> clazz) throws GeneralSecurityException, IOException {
    //do some stuff and get the content, which is a JSON 

    final T result = (T)JsonMapper.fromJsonToJavaObject(decryptedJson, clazz);

    return result;
}

希望这会有所帮助

答案 1 :(得分:1)

您说:

  

不应更改Json映射器方法。基本上可以。

我不会这么说。就像objectMapper.readValue一样,它也需要参数化。

将其更改为此:

public static <T> T fromJsonToJavaObject(String jsonObject, Class<T> clazz) throws JsonParseException, JsonMappingException, IOException
{
    return objectMapper.readValue(jsonObject, clazz);
}

并避免在此处投射:(T)JsonMapper.fromJsonToJavaObject