Как я могу удалить предупреждение о непроверенном приведении в Java?

у меня есть этот кусок кода:

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;

public class ClientLookup<T extends Remote> {
 private T sharedObject;

 public void lookup(String adress) throws MalformedURLException, RemoteException, NotBoundException {
   sharedObject = (T) Naming.lookup(adress);
 }

 public T getSharedObject() {
   return sharedObject;
 }
}

Часть с "(T) Naming.lookup(address)" выдает мне предупреждение: "Безопасность типов: непроверенное приведение от Remote к T"

Я не хочу использовать "@SuppressWarnings("unchecked")", я просто хочу знать, почему отображается предупреждение, когда "T extends Remote" и исправить это (для чистого кода)

Спасибо.


person user252098    schedule 16.01.2010    source источник


Ответы (3)


«Непроверенное приведение» здесь означает, что Java не может проверить, действительно ли объект, подлежащий приведению, имеет тип T во время выполнения, поскольку тип T во время выполнения неизвестен. В лучшем случае он может подтвердить, что он действительно относится к типу Remote.

Общим решением этой проблемы является предоставление объекта Class<T> для определения типа:

public class ClientLookup<T extends Remote> {
  private T sharedObject;
  private Class<T> clazz;

  public ClientLookup(Class<T> clazz) {
    this.clazz = clazz;
  }

  public void lookup(String adress) throws MalformedURLException, RemoteException, NotBoundException {
    sharedObject = clazz.cast(Naming.lookup(adress));
  }

  public T getSharedObject() {
    return sharedObject;
  }
}

Таким образом, вы делаете тип T явным и известным во время выполнения.

person Joachim Sauer    schedule 16.01.2010
comment
+1, молодец, предоставив работающее решение. Но я в ужасе от того, через что вам придется пройти через Java! Возможно, пришло время Scala. - person Carl Smotricz; 16.01.2010
comment
@Карл - тогда иди... и не хлопай дверью на выходе :-) - person Stephen C; 16.01.2010

Поскольку Naming.lookup() возвращает Remote, поэтому ваш бросок фактически не проверен.

Если бы у вас был дескриптор класса T, вы могли бы использовать:

private Class<T> clazz;
clazz.cast(Naming.lookup(address)); 

который вернет T. Из-за стирания вам нужно будет указать класс в конструкторе или использовать какой-либо другой хакерский прием, например: MoreTypes.java.

person miaubiz    schedule 16.01.2010

Есть несколько предупреждений, связанных с обобщениями приведения типов, от которых мне так и не удалось избавиться. Я просто сдался и использовал @SuppressWarnings.

Другая альтернатива, зависящая от IDE, состоит в том, чтобы сделать компилятор менее чувствительным к проблемам. Eclipse позволяет выборочно отключать определенные предупреждения. Я нахожу предупреждение «отсутствующий серийный UID» в классах графического интерфейса Swing (среди прочих) довольно раздражающим излишним и деактивировал их. Если меня слишком раздражают эти предупреждения, их постигнет та же участь.

person Carl Smotricz    schedule 16.01.2010