简体   繁体   English

如何检查在Java中收到的通用my方法?

[英]How to check the generic my method received in Java?

I have a set method that need to accept 2 kind of generics : 我有一个set方法,需要接受2种泛型:

  • Map<Long,Map<String,Object>> , and Map<Long,Map<String,Object>>
  • Map<Long,Map<String,String>>

However I need to set it as Map<Long,Map<String,String>> 但是我需要将其设置为Map<Long,Map<String,String>>

I know that String is an Object, so in the parameter I can use Map<Long,Map<String,Object>> , however I don't want to undergo a conversion if there no need to. 我知道String是一个对象,因此在参数中我可以使用Map<Long,Map<String,Object>> ,但是我不需要进行转换。 Using instanceof seems not working, throwing me with error: 使用instanceof似乎无法正常工作,并抛出错误:

Cannot perform instanceof check against parameterized type Map<Long,Map<String,String>> . 无法对参数化类型Map<Long,Map<String,String>>执行instanceof检查。 Use the form Map<?,?> instead since further generic type information will be erased at runtime 请改用Map<?,?>形式Map<?,?>因为在运行时将删除更多的泛型类型信息

Below is current codes I have now. 以下是我现在拥有的当前代码。

public void setRates(Map<Long,Map<String,Object>> inputRates){

    if(inputRates!=null){
        Map<Long,Map<String,String>> result = new HashMap<>();
        // if <Map<Long,Map<String,String>> do below :
        if(inputRates instanceof Map<Long,Map<String,String>>){
        //instanceof not working....   
            this.rates= inputRates;
        }else{
            // if really Map<Long,Map<String,Object>> do below - converting Object to String
            for (Map.Entry<Long, Map<String,Object>> entry1 : inputRates.entrySet()) {
                Map<String,String> resultMap = new HashMap<>(); 

                Long key = entry1.getKey();
                Map<String,Object> inputMap = entry1.getValue();
                for(Map.Entry<String,Object> entry2 : inputMap.entrySet()) { 
                    String key2 = entry2.getKey();
                    Object value2 = entry2.getValue();
                    if(value2!=null){
                        resultMap.put(key2, value2.toString());  
                    }else{
                        resultMap.put(key2, null);  
                    }
                }
                result.put(key, resultMap);
            }
            this.rates = result;
        } 
    }
}

Any idea on how I implement this? 我如何实现这个想法?

You can have a generic method . 您可以使用generic method

public <T> void setRates(Map<Long,Map<String, T>> inputRates){ }

Then use generic type T in your method's body. 然后在方法的主体中使用通用类型T

Generics are erased after compilation. 泛型在编译后被擦除。 So you could never use instanceof with a parameterized type class : 因此,您永远不能将instanceof与参数化类型类一起使用:

if(inputRates instanceof Map<Long,Map<String,String>>){

Using instanceof with Map<?,?> will be useless either as it is still broader. instanceofMap<?,?>将是无用的,因为它仍然更广泛。 Map<Object, Object> being broader than Map<String,Object> . Map<Object, Object>Map<String,Object>宽。

If the clients of your method declare a broader generic variable : Map<String,Object>String,Object> , you is stuck to cast Object to String in the processing of the Map . 如果您的方法的客户端声明了更广泛的泛型变量: Map<String,Object>String,Object> ,则在Map的处理过程中,您将必须将ObjectString

Other option : create a new method with Map<Long,Map<String,String>> as parameter. 其他选项:使用Map<Long,Map<String,String>>作为参数创建一个新方法。
The client would call so the first one or the second according to what one manipulates. 客户端会根据操作者的要求呼叫第一个或第二个。

You can overload with named classes such: 您可以使用以下命名类重载:

class ObjectMap extends Map<Long,Map<String,Object>>{}
class StringMap extends Map<Long,Map<String,String>>{}
public void setRates(ObjectMap inputRates){ }
public void setRates(StringMap inputRates){ }

They will work as their parametrized parts but you will need to instantiate then instead. 它们将作为参数化的部分工作,但是您需要实例化然后代替。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM