wrappers ejemplos concepto java reflection wrapper

ejemplos - concepto de wrapper en java



Una forma sencilla de obtener el tipo de clase envoltorio en Java (7)

Tengo un código donde necesito pasar la clase de un campo en un método. Debido a la mecánica de mi código, solo puedo manejar objetos de referencia y no primitivos. Quiero una manera fácil de determinar si el tipo de un Field es primitivo y lo cambia por la clase de envoltura adecuada. Así que en código lo que hago hasta ahora es algo como esto:

Field f = getTheField(); // Dummy method that returns my Field Class<?> c = f.getType(); if (c == int.class) { c = Integer.class; } else if (c == float.class) { c = Float.class; } // etc myMethod(c);

Esto funciona bien, excepto por el hecho de que necesito verificar explícitamente todos los tipos primitivos e intercambiarlos con la clase envoltura apropiada. Ahora sé que no hay tantos tipos primitivos y que no será un problema simplemente enumerarlos todos, pero me preguntaba si habría una forma más fácil y elegante de hacerlo.


(Idea) Obtenga el nombre de la clase y haga mayúscula en la primera letra, luego llame a Class.forInstance (className) .newInstance (primitiva). Las excepciones son "char" -> Carácter y "int" -> Entero

Class c=Primitive class object if (c.isPrimitive()) { if (c == char.class) { Object wrapper=new Character(primitive var); } if (c == int.class) { Object wrapper=new Integer(primitive var); } else { String name=c.getName(); try { Class<?> c2=Class.forName("java.lang."+name.substring(0,1).toUpperCase()+name.substring(1,name.length())); Object wrapper=c2.getConstructor(c).newInstance(primitve_var); } catch (ClassNotFoundException ex) { System.out.println("RROR"); } } }


Esta es otra manera si no necesita un código altamente optimizado:

Class<?> primitive=long.class; Class<?> boxed=Array.get(Array.newInstance(primitive,1),0).getClass(); System.out.println(primitive.getName()); System.out.println(boxed.getName());

(Edición / adición de explicación)

Al principio, era para ver si Java tiene un método para darle la clase contenedora cuando se le da un tipo primitivo. No se pudo encontrar ninguno.

Luego, fue para ver si puede hacer que Java cree un valor primitivo cuando se le da un tipo primitivo (de alguna manera puede sacar un objeto de él). No se pudo encontrar una manera de hacer esto.

Pero luego se descubrió que PUEDE hacer que Java cree una matriz de valores primitivos cuando se le da un tipo primitivo. Y luego hay un método Java que le da un objeto del tipo de envoltura del elemento de matriz (que es primitivo). Una vez que tenga el objeto, puede obtener el tipo.

Así que aquí es cómo funciona todo:

El método Array.newInstance () crea una matriz del tipo que especifique, ya sea primitivo u objeto. En el caso de un objeto, todos los elementos son de tipo objeto pero inicializados en nulo. En el caso de los primitivos, los elementos son de tipo primitivo. Pero el elemento primitivo variable / matriz no puede ser nulo, por lo que tienen el valor predeterminado del tipo primitivo, por ejemplo, int será cero. Por lo tanto ningún elemento será nulo. Y ahora, si intenta obtener el valor de un elemento utilizando Array.get (), Array.get () no tiene más remedio que colocar ese valor primitivo en un objeto, por ejemplo, int to Integer, porque Array.get () puede '' t devuelve el valor primitivo. Ahora tiene un objeto del tipo de boxeo (envoltura) de su tipo primitivo original. Finalmente, llamar a Object.getClass () le da el tipo de boxeo (ajuste).

Este truco funciona con cualquier tipo primitivo que tenga en Java hoy y en el futuro.


Puede llamar a class.isPrimitive () para saber si es una primitiva o no, sin embargo, no existe un método de boxeo para convertir las clases dentro del JDK. Hay al menos un error abierto relacionado con esto.


También hay com.sun.beans.finder.PrimitiveWrapperMap # getType (primitiveName). Pero, por supuesto, no se recomienda usar clases del paquete "com.sun" ...


Utilizo la biblioteca de Google Collections en mi respuesta, ya que estoy malcriada, pero probablemente puedas ver cómo hacerlo con HashMaps simples si lo prefieres.

// safe because both Long.class and long.class are of type Class<Long> @SuppressWarnings("unchecked") private static <T> Class<T> wrap(Class<T> c) { return c.isPrimitive() ? (Class<T>) PRIMITIVES_TO_WRAPPERS.get(c) : c; } private static final Map<Class<?>, Class<?>> PRIMITIVES_TO_WRAPPERS = new ImmutableMap.Builder<Class<?>, Class<?>>() .put(boolean.class, Boolean.class) .put(byte.class, Byte.class) .put(char.class, Character.class) .put(double.class, Double.class) .put(float.class, Float.class) .put(int.class, Integer.class) .put(long.class, Long.class) .put(short.class, Short.class) .put(void.class, Void.class) .build();

Es extraño que nada exista en el JDK para esto, pero en realidad nada lo hace.

EDIT: había olvidado totalmente que lanzamos esto:

http://google.github.io/guava/releases/21.0/api/docs/com/google/common/primitives/Primitives.html

Tiene el método wrap (), además de unwrap () y algunas otras cosas incidentales.



Class<?> toWrapper(Class<?> clazz) { if (!clazz.isPrimitive()) return clazz; if (clazz == Integer.TYPE) return Integer.class; if (clazz == Long.TYPE) return Long.class; if (clazz == Boolean.TYPE) return Boolean.class; if (clazz == Byte.TYPE) return Byte.class; if (clazz == Character.TYPE) return Character.class; if (clazz == Float.TYPE) return Float.class; if (clazz == Double.TYPE) return Double.class; if (clazz == Short.TYPE) return Short.class; if (clazz == Void.TYPE) return Void.class; return clazz; }