Java Object return type vs. Generic Methods

后端 未结 4 716
甜味超标
甜味超标 2021-02-18 16:28

I saw several questions about generic return type, but none answers my question.
If there is no bound for any of the arguments, such as the following method in JayWay :

4条回答
  •  余生分开走
    2021-02-18 17:12

    Generics work by the compiler inserting invisible casts into your code.

    For example, before generics were added to the language you'd have to do this.

    List list = new ArrayList();
    list.add("Foo");
    list.add("Bar");
    String str0 = (String) list.get(0);
    String str1 = (String) list.get(1);
    

    This was very annoying. Because get() returned Object, you had to cast every single time you wanted to get a String from the List.

    Nowadays, List is generic, and get() returns T, so you can just do this.

    List list = new ArrayList<>();
    list.add("Foo");
    list.add("Bar");
    String str0 = list.get(0);
    String str1 = list.get(1);
    

    What is happening here is that the compiler turns the new version into the old version by adding the casts for you, but they're still there.

    However, the entire point of generics is that these compiler generated casts are guaranteed to be safe - i.e. they can't possibly throw a ClassCastException at runtime.

    In my opinion, if you use generics to hide casts that are not guaranteed to be safe, just because they're annoying, it is an abuse of the feature.

    Whether it's a generic method and you do

    Boolean a = JsonPath.read(currentRule, "$.logged");
    

    or it returns Object and you do

    Boolean a = (Boolean) JsonPath.read(currentRule, "$.logged");
    

    both versions could throw a ClassCastException at runtime, so I think it's better if you are forced to cast so that at least you are aware that you're doing something that could fail.

    I consider it bad practice for the return type of a generic method to involve the type parameter T if the method parameters do not, unless the returned object cannot be used in a way that compromises type safety. For example,

    public static  List emptyList()
    

    in Collections is ok (the list is empty so it can't contain an element of the wrong type).

    In your case, I think the read method should not be generic and should just return Object.

提交回复
热议问题