我有一个使用泛型和对象序列化的简单服务器。(T 是输入格式,U 是输出格式)。仅处理输入的简化版本如下所示:
public class Server <T, U> implements Runnable {
@override
public void run () {
try (ObjectInputStream inReader = new ObjectInputStream (this.connection.getInputStream ())) {
T lastObj;
while (true) {
lastObj = (T) inReader.readObject ();
System.out.println (lastObj.getClass ().getName ());
if (null != lastObj) {
this.acceptMessage (lastObj);
}
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger (this.getClass ().getName ()).log (Level.SEVERE, ex.getMessage (), ex);
}
}
}
如果我启动服务器
Server <Integer, String> thisServer = new Server ();
那么我希望它只接受整数对象并返回字符串作为输出。
但是,我使用了一个从 System.in 读取的简单客户端,用于测试并将字符串发送到服务器。令我惊讶的是,服务器接受了输入。只是为了确保它确实接受了一个不是 TI 类型的对象,添加了这一行来回显最后一个对象是什么类。
System.out.println (lastObj.getClass ().getName ());
这实际上输出了 Java.lang.String。
这完全出乎意料。我认为泛型应该允许您传递未在类本身中指定的类型的对象而不必强制转换对象?转换为 T 似乎也没有效果。
这意味着理论上我可以通过向服务器(或其消费者)提供它不期望的类型的 Java 对象来攻击它。虽然这不必非常强大(因为它是一个学术项目而不是生产软件),但我认为知道您使用 readObject 获得的对象不是您想要的对象,因此您可以处理它是很重要的。
我尝试添加以下内容,但它只是被标记为编译时错误。
if (lastObj instanceof T) {
}
我将如何正确处理这个问题?