Type safety: Unchecked cast from Object to ArrayList

后端 未结 5 697
情深已故
情深已故 2020-12-09 08:36

Here is a part of a program that sends an ArrayList from a server to a client. I want to remove the warning about the last line in this code:

Client code:

         


        
相关标签:
5条回答
  • 2020-12-09 08:47

    It's impossible to avoid this warning. readObject() returns an Object. You need to cast it. And casting to a generic type will always generate such a warning.

    If you want to make your code as clean as possible, which is a good idea, you should respect the Java naming conventions though, and make variable names start with a lowercase letter.

    0 讨论(0)
  • 2020-12-09 08:51

    I was running into a similar problem as OP and found a good solution with a combination of comment from @VGR and Java 1.8 method for Arrays.

    I will provide my answer in terms of OP's question, so it is generic and hopefully helps others:

    1. Instead of returning a collection (list), return an array from the server. Covert collection to an array using the following on the server side code:

      myVariableList.toArray(new MyVariable[0]);

      If performance is an issue with above, following could be used, so that array does not need to be resized:

      myVariableList.toArray(myVariableList.size());

    2. On client side convert array of object, to an array of MyVariable class.

      This is specific to JAVA 8.

      MyVariable[] myVarArr = Arrays.stream(ois.readObject()).toArray(MyVariable[]::new);

    3. Then, finally convert Array to a Collection (list).

      List<MyVariable> myList = Arrays.asList(myVarArr);

    Thanks.

    0 讨论(0)
  • 2020-12-09 09:00

    Try this

    Object obj = ois.readObject();
    // Check it's an ArrayList
    if (obj instanceof ArrayList<?>) {
      // Get the List.
      ArrayList<?> al = (ArrayList<?>) obj;
      if (al.size() > 0) {
        // Iterate.
        for (int i = 0; i < al.size(); i++) {
          // Still not enough for a type.
          Object o = al.get(i);
          if (o instanceof MyVariable) {
            // Here we go!
            MyVariable v = (MyVariable) o;
            // use v.
          }
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-09 09:01

    I don't like that, but you can have a container (sort of an alias or typedef):

    // add "implements Serializable" in your case
    private static class MyVariableList {
        public List<MyVariable> value;
    }
    

    And work with MyVariableList instead. That way you explicitly provide enough information to the compiler to do type checking in runtime.

    0 讨论(0)
  • 2020-12-09 09:03

    I also ran into a similar situation and was able to solve it. My solution, applied to the example of the OP is this:

    myList = (ArrayList<Someclass>) Arrays.asList( (Someclass[]) ois.readObject() );
    

    I have changed the naming-conventions (like suggested by someone, already) to standard Java (objects start with lowercase-characters) and I have renamed the Class MyVariable to Someclass to make it explicit, that this really applies to any class (and not just Variables). I'm also assuming, that the corresponding object to myList on the server-side of type ArrayList<Someclass> has been written to the stream as an Array Someclass[]. Note, that this is easily done and analogous to the first part of what abhishek already suggested, but my solution differs on the last step insofar as:

    1. I'm avoiding to call Arrays.stream
    2. It's easier to read and quickly perceived as a simple (without further logic) and checked (not generating a warning) cast.
    0 讨论(0)
提交回复
热议问题