0

为什么下面的代码不会抛出异常?

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("unchecked")
public class MainRunner {
    public static void main(String[] args) {
    List<String> s = new ArrayList<String>() {
        {
        add("a");
        add("1");
        add("1");
        }
    };
    // List<Integer> i = (List<Integer>) listConvertor(s, new Integer("1"));
    List<Integer> i = (List<Integer>) listConvertor(s, Integer.class);
    System.out.println(i);
    }

    @SuppressWarnings("unchecked")
    public static <T, P> List<?> listConvertor(List<T> inputList, P outputClass) {
    List<P> outputList = new ArrayList<P>(inputList.size());
    for (T t : inputList) {
        outputList.add((P) t); // shouldn't be classCastException here?
    }

    return outputList;

    }

}

我想返回List<P>而不是List<?>. 但是当我写的时候List<P>,它的意思是List<Class<P>>。即在上述情况下,这意味着List<Class<Integer>>,但我想List<Integer>作为回报。

我想要下面的代码:(这样我就不必在方法返回时再次转换)

List<Integer> i =   listConvertor(s, Integer.class);
        System.out.println(i);
        }

        @SuppressWarnings("unchecked")
        public static <T, P> List<P> listConvertor(List<T> inputList, P outputClass) {
        List<P> outputList = new ArrayList<P>(inputList.size());
        for (T t : inputList) {
            outputList.add((P) t); // shouldn't be classCastException here?
        }

        return outputList;

        }

    }
4

5 回答 5

1
public static <T, P> List<P> listConvertor(List<T> inputList, Class<P> outputClass) {

请记住,您传递的是一个类对象,而不是一个整数对象。

于 2012-07-27T12:03:22.780 回答
1

不,当然它不会抛出异常。泛型用于编译时检查,而不是运行时检查。在运行时,您的所有列表都是List<Object>,并且强制转换是由 JVM 隐式进行的。


编辑:在您的代码中,

for (T t : inputList) {
  outputList.add((P) t); // shouldn't be classCastException here?
}

实际上编译为

for (Object t : inputList) {
  outputList.add((Object) t); // shouldn't be classCastException here? -- no
}

例如,使用您的代码,如果您这样做,i.get(0).getClass()您将获得a ClassCastException,因为该项目无法从转换StringInteger.class注意:同样适用,但是您这样做,因为您不能将 a 隐式String转换为Integer. 句点。)

如果这确实是您想要做的,强制T转换为P(例如,将字符串强制转换为数值),那么我建议您使用另一种模式。例如 :

static interface ClassConverter<F,T> {
    public T convert(F o);
}

static class StringToIntConverter implements ClassConverter<String,Integer> {
    public Integer convert(String o) {
        try {
            return Integer.parseInt(o);
        } catch (NumberFormatException e) {
            return 0;
        }
    }
}

public static void main(String[] args) {
    List<String> s = new ArrayList<String>() {
        {
        add("a");
        add("1");
        add("1");
        }
    };
    // List<Integer> i = (List<Integer>) listConvertor(s, new Integer("1"));
    List<Integer> i = (List<Integer>) listConvertor(s, new StringToIntConverter());
    System.out.println(i);
    System.out.println(i.get(0).getClass().getName());
}

public static <T, P> List<P> listConvertor(List<T> inputList, ClassConverter<T, P> c) {
    List<P> outputList = new ArrayList<P>(inputList.size());
    for (T t : inputList) {
        outputList.add(c.convert(t)); // cast handled by the class method == safer
    }

    return outputList;
}

您需要做的就是为ClassConverter您希望转换的任何类型实现接口并将其传递TP您的listConverter方法。

于 2012-07-27T12:14:03.030 回答
1

这应该以最小的麻烦完成这项工作:

public static <T, P> List<P> listConvertor(List<T> inputList, Class<P> outputClass) {
    List<P> outputList = new ArrayList<P>(inputList.size());
    for (T t : inputList) {
        if( !outputClass.isInstance(t) )
            throw new ClassCastException("Faked CCException");
        @SuppressWarnings("unchecked")
        P p = (P) t;
        outputList.add(p);
    }

    return outputList;
}
  • 呼叫方没有演员表
  • 如果源列表中有不适当的类型,则异常。
于 2012-07-27T12:35:07.937 回答
0
import java.util.ArrayList;
import java.util.List;

public class MainRunner {
  public static void main(String[] args) {
    List<String> s = new ArrayList<String>() {
      {
        add("a");
        add("1");
        add("1");
      }
    };

    List<Integer> i = listConvertor(s, Integer.class);
    System.out.println(i);
  }

  public static <T, P> List<P> listConvertor(List<T> inputList, Class<P> outputClass) {
    List<P> outputList = new ArrayList<P>(inputList.size());
    for (T t : inputList) {
      outputList.add((P) t); // shouldn't be classCastException here?
    }

    return outputList;
  }
}
于 2012-07-27T12:03:49.057 回答
0

与@AH 的答案相同,但使用大大简化Class.cast()了,并且也摆脱了不必要的T

public static <P> List<P> listConvertor(List<?> inputList, Class<P> outputClass) {
    List<P> outputList = new ArrayList<P>(inputList.size());
    for (Object t : inputList) {
        P p = outputClass.cast(t);
        outputList.add(p);
    }

    return outputList;
}
于 2012-07-27T18:07:34.813 回答