Тип безопасности Hashtable - PullRequest
3 голосов
/ 24 мая 2019

Я десериализирую Hashtable в Hashtable экземпляр с использованием приведения и получаю это предупреждение: Type safety: Unchecked cast from Object to Hashtable<Date,String>.

код: list = ((Hashtable<Date,String>)oos.readObject());

Есть ли способ решить это предупреждение?

Ответы [ 2 ]

7 голосов
/ 24 мая 2019

Простой ответ: нет, нет.

Видите ли, подпись этого метода гласит: он возвращает Object :

public final Object readObject ()

Таким образом, вы должны разыграть здесь. И, таким образом, нет другого способа, кроме подавления предупреждения.

И другого пути нет. Имейте в виду: идея в том, что вы можете записать любой вид java-объекта в такие потоки. И, таким образом, вы также можете «извлечь» из него любой предмет. Таким образом, Object является единственным возвращаемым типом, который имеет здесь смысл.

Конечно, в случае с обобщенными наборами Java результат может быть некоторым T или некоторым T, который дополнительно ограничен. Но тогда это все равно будет только время компиляции, так как ноль гарантирует, что все получится так, как ожидается во время выполнения.

1 голос
/ 24 мая 2019

Да, есть.

    Object obj = oos.readObject();
    if (obj instanceof Hashtable) {
        list = ((Hashtable<?, ?>) obj);
        final Date dateKey = Date.from(Instant.parse("2019-05-01T00:00:00Z"));
        Object value = list.get(dateKey);
        if (value == null) {
            System.out.println("No value found for key " + dateKey);
        } else if (value instanceof String) {
            System.out.println("Value read from list was " + value);
        } else {
            System.out.println("list contained unexpected value type " + value.getClass());
        }
    } else {
        System.out.println("Unexpected type read: " + obj.getClass());
    }

Есть два шага:

  • Убедитесь, что объект, считанный из oos, является Hashtable (Кстати, очень старыйкласс, который мы обычно не используем).
  • Убедитесь, что Hashtable содержит Date ключи и String значения (кстати, еще один очень старый класс, который мы обычно не используембольше).

Во время выполнения мы можем проверить, является ли объект, считанный из oos, от Hashtable до obj instanceof Hashtable, но из-за того, как работают дженерики Java, мы не можем проверить, является лиHashtable<Date, String>.Поэтому мы просто приводим к Hashtable<?, ?>.Компилятор может видеть проверку instanceof и не выдает никаких предупреждений из-за этого приведения.

Метод get Hashtable принимает любой Object в качестве аргумента (по историческим причинам), поэтомунет проблем с передачей Date к нему.Наша вторая проверка имеет значение, возвращаемое из get: мы хотим знать, является ли это String, как и ожидалось.Если это так, мы можем безопасно привести к String (не показано во фрагменте).

Если Hashtable не содержит сопоставления для предоставленного Date, get возвращает null.Это, в свою очередь, может быть связано с тем, что тип ключа Hashtable не был Date, как ожидалось, или просто потому, что наш конкретный Date не присутствовал в качестве ключа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...