sirve setcontentareafilled que para metodos icon example create clase boton actionperformed java generics raw-types

java - setcontentareafilled - ¿Por qué se prefiere la clase<?> A la clase



que es el boton en java (5)

Si declaro una clase como campo:

Class fooClass;

Eclipse me da la advertencia:

La clase es un tipo sin procesar. Las referencias a clase genérica deben estar parametrizadas.

¿Qué significa esto en la práctica? ¿Y por qué me urge hacerlo? Si le pido a Eclipse una "solución rápida" me da:

Class<?> fooClass;

que no parece agregar mucho valor pero ya no da una advertencia.

EDITAR: ¿Por qué la clase es genérica? ¿Podría por favor dar un ejemplo de parametrización, es decir, podría haber un uso válido de otra cosa que no sea <?> ?

EDITAR: ¡GUAU! No me había dado cuenta de las profundidades de esto. También he visto el Java Puzzler y ciertamente me asustan las trampas para osos. Así que siempre usaré

Class<MyString> myStringClass = MyString.class;

más bien que

Class myStringClass = MyString.class;

(Pero después de usar Java desde el primer día, realmente no noté cuando Class se convirtió en genérico);

NOTA: He aceptado @oxbow_lakes ya que esto tiene sentido para mí, pero es claramente un área muy complicada. Class<MyString> a todos los programadores a utilizar la Class<MyString> específica Class<MyString> lugar de la Class . Y la Class<?> Es mucho más segura que la Class .


que no parece agregar mucho valor pero ya no da una advertencia.

Tienes razón. Pero esto podría agregar valor:

Class<FooClass> fooClass;

o, si es más apropiado:

Class<? extends FooClass> fooClass;

o

Class<FooInterface> fooClass;

Al igual que con los genéricos en general, puede mejorar la seguridad de los tipos especificando qué clase de clase desea que contenga la variable. La advertencia contra los tipos en bruto está destinada a detectar fragmentos de código donde no se utiliza este potencial. Al declarar Class<?> Básicamente estás diciendo que "esto está destinado a mantener cualquier clase de clase".


Tipos crudos y comodines ilimitados

Ninguna de las respuestas anteriores ha abordado realmente por qué debería preferir la Class<?> lugar de la Class , ya que parece que la primera no ofrece más información que la segunda.

El motivo es que, el tipo sin formato , es decir, Class , impide que el compilador realice comprobaciones de tipo genérico. Es decir, si utiliza tipos brutos, subvierte el sistema de tipos . Por ejemplo:

public void foo(Class<String> c) { System.out.println(c); }

Se puede llamar así (se compilará y ejecutará):

Class r = Integer.class foo(r); //THIS IS OK (BUT SHOULDN''T BE)

Pero no por:

Class<?> w = Integer.class foo(w); //WILL NOT COMPILE (RIGHTLY SO!)

¿Usando siempre la forma no cruda, incluso cuando debe usar ? Debido a que no puede saber cuál es el parámetro de tipo (o está limitado por), le permite al compilador razonar sobre la corrección de su programa más completamente que si usó tipos en bruto.

¿Por qué tienen tipos crudos en absoluto?

La especificación del lenguaje Java dice:

El uso de tipos brutos se permite solo como una concesión a la compatibilidad de código heredado

Siempre debes evitarlos. ¿El comodín sin límites ? Probablemente se describa mejor en otro lugar, pero esencialmente significa "esto está parametrizado en algún tipo, pero no sé (o me importa) qué es" . Esto no es lo mismo que los tipos brutos , que son una abominación y no existen en otros idiomas con genéricos, como Scala .

¿Por qué la clase está parametrizada?

Bueno, aquí hay un caso de uso. Supongamos que tengo alguna interfaz de servicio:

public interface FooService

Y quiero inyectar una implementación de la misma, utilizando una propiedad del sistema para definir la clase que se usará.

Class<?> c = Class.forName(System.getProperty("foo.service"));

No sé en este punto que mi clase es del tipo correcto:

//next line throws ClassCastException if c is not of a compatible type Class<? extends FooService> f = c.asSubclass(FooService.class);

Ahora puedo instanciar un FooService :

FooService s = f.newInstance(); //no cast


El Javadoc de la clase Class da una idea de por qué existen parámetros de tipo para esta clase:

T - el tipo de la clase modelada por este objeto de Class . Por ejemplo, el tipo de String.class es Class<String>. Use Class<?> Si la clase que se está modelando es desconocida.

El uso de este parámetro de tipo no es tan obvio, pero una mirada superficial al código fuente de la clase indica por qué a veces el parámetro de tipo es necesario. Considere la implementación del método newInstance :

public T newInstance() throws InstantiationException, IllegalAccessException { if (System.getSecurityManager() != null) { checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader()); } return newInstance0(); }

Si no se ha dado cuenta, el tipo de objeto devuelto por este método es el del parámetro de tipo. Esto es útil en el código que utiliza mucha reflexión, y donde uno quisiera tener un cuidado especial para garantizar que los objetos del tipo correcto estén siendo instanciados.

Teniendo en cuenta el ejemplo de la pregunta, si la instancia de la clase fue declarada como:

Class<String> fooClass; Class<Integer> barClass; String aString;

entonces, es casi imposible tener el siguiente código para compilar:

aString = barClass.newInstance();

En resumen, si va a trabajar con jerarquías de clases y desea imponer estrictas comprobaciones de tiempo de compilación para asegurarse de que su código no necesita realizar muchas verificaciones de instanceof , entonces es mejor que especifique el tipo de clase que desea utilizar. Especificando ? permite todos los tipos, pero habría casos en los que tendrá que ser más específico.


Porque usar tipos brutos en lugar de tipos parametrizados tiene muchos escollos.

Una de las cuales es que si se usa un tipo sin procesar, todos los genéricos de la clase se pierden. Incluso los definidos por método.


Porque, desde JDK 5, la Class ahora tiene un tipo parametrizado, lo que hace que la Class sea ​​un objeto genérico. Esto es necesario (desde la introducción de Genéricos) para que el compilador realice la comprobación de tipos (en el momento de la compilación, por supuesto).

Class<?> Significa una "clase de desconocido" ? dónde ? Es un wildcard genérico. Significa que una fooClass de clase de tipo Class<?> Acepta una Class cuyo tipo no coincide con nada.

Ejemplo típico:

Class<?> classUnknown = null; classUnknown = ArrayList.class; //This compiles.

Puede, efectivamente, proporcionar un Tipo Parametrizado para ser más específico, por ejemplo:

Class<ArrayList> = ArrayList.class;

PS Tenga en cuenta que la Class<List> listClass = ArrayList.class; no compilará (aunque ArrayList esté de la Lista) pero (como Mark Peters mencionó en el comentario) Class<? extends List> listClass = ArrayList.class; Class<? extends List> listClass = ArrayList.class; Se compila (gracias al comodín).