Java中有没有办法通过一个方法声明返回不同的类型?
public Object loadSerialized(String path) {
Object tmpObject;
try {
FileInputStream fis = new FileInputStream(path);
ObjectInputStream ois = new ObjectInputStream(fis);
tmpObject = (Object) ois.readObject();
ois.close();
fis.close();
return tmpObject;
}
catch(FileNotFoundException e) {return null;}
catch(Exception e) {}
}
我希望这个方法返回一个Object,然后我在函数调用中将它强制转换为正确的类型。这就是我的想法,但它并没有像这样工作。我需要某种通用的返回类型才能执行此操作吗? 什么是解决这个问题的最佳方法?
答案 0 :(得分:5)
要安全地执行此操作,您需要将所需类型作为Class对象传递:
public <T> T loadSerialized(String path, Class<T> targetType) {
try (ObjectInputStream ois = new ObjectInputStream(
new BufferedInputStream(
new FileInputStream(path)))) {
Object tmpObject = (Object) ois.readObject();
return targetType.cast(tmpObject);
} catch (FileNotFoundException e) {
return null;
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
当你可能写return (T) tmpObject;
时,会产生编译器警告,因为它不安全:因为编译器只知道T可能是Object的某个后代(或者Object本身) ),编译器生成(Object)
,这与什么都不做是一样的。代码盲目地假设返回的对象是T类型,但如果不是,当程序试图调用T中定义的方法时,您将得到一个惊喜异常。一旦您对对象进行反序列化,最好知道它是否是您期望的类型。
如果您对List进行不安全的转换,也会发生类似情况:
List<Integer> numbers = Arrays.asList(1, 2, 3);
List<?> list = numbers;
List<String> names = (List<String>) list; // Unsafe!
String name = names.get(0); // ClassCastException - not really a String!
答案 1 :(得分:1)
您可以在返回类型中使用通用。它可能看起来像这样。简单来说,编译器根据方法的调用方式为T
选择最佳类型。然后铸造发生在方法内,而不是在外面。
请注意,我使用了try-with-resources语法,以避免与关闭流混乱。
public <T> T loadSerialized(String path) throws IOException, ClassNotFoundException {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path))) {
return (T) ois.readObject();
}
}