una sorteo rifa programa loto loteria hacer como java reflection guava

sorteo - loto java



Obtener el valor predeterminado para los tipos de primitiva Java (8)

Basado en la respuesta de Jack Leow , creé esta clase:

/** <P>{@code java InitializedObjectUtil}</P> **/ public class InitializedObjectUtil { public static final void main(String[] igno_red) { printDefault("boolean"); printDefault("char"); printDefault("byte"); printDefault("short"); printDefault("int"); printDefault("long"); printDefault("float"); printDefault("double"); printDefault("java.lang.AnythingAndEverythingElse"); } private static final void printDefault(String s_type) { Object oDflt = InitializedObjectUtil.getForClassName(s_type); System.out.println(s_type + " default is /"" + oDflt + "/""); } /** <P>The default value for a boolean is {@code false}.</P> <P>Viewed 1/21/2014 <BR><CODE><A HREF="http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html</A></CODE>:</P> <P><B>Default Values:</B> </P> <P>It''s not always necessary to assign a value when a field is declared. Fields that are declared but not initialized will be set to a reasonable default by the compiler. Generally speaking, this default will be zero or null, depending on the data type. Relying on such default values, however, is generally considered bad programming style. The following chart summarizes the default values for the above data types.</P> <PRE>{@literal Data Type Default Value (for fields) -------------------------------------- byte 0 short 0 int 0 long 0L float 0.0f double 0.0d char ''/u0000'' String (or any object) null boolean false}</PRE> @see #getForClass(String) getForClass(s) @see #getForClassName(String) getForClassName(s) @see #DEFAULT_CHAR @see #DEFAULT_BYTE @see #DEFAULT_SHORT @see #DEFAULT_INT @see #DEFAULT_LONG @see #DEFAULT_FLOAT @see #DEFAULT_DOUBLE **/ public static final Boolean DEFAULT_BOOLEAN = false; /** <P>The default value for a char {@code ''/u0000''}.</P> @see #DEFAULT_BOOLEAN **/ public static final Character DEFAULT_CHAR = ''/u0000''; /** <P>The default value for a byte is {@code 0}.</P> @see #DEFAULT_BOOLEAN **/ public static final Byte DEFAULT_BYTE = 0; /** <P>The default value for a short is {@code 0}.</P> @see #DEFAULT_BOOLEAN **/ public static final Short DEFAULT_SHORT = 0; /** <P>The default value for a int is {@code 0}.</P> @see #DEFAULT_BOOLEAN **/ public static final Integer DEFAULT_INT = 0; /** <P>The default value for a long is {@code 0L}.</P> @see #DEFAULT_BOOLEAN **/ public static final Long DEFAULT_LONG = 0L; /** <P>The default value for a float {@code 0.0f}.</P> @see #DEFAULT_BOOLEAN **/ public static final Float DEFAULT_FLOAT = 0.0f; /** <P>The default value for a double {@code 0.0d}.</P> @see #DEFAULT_BOOLEAN **/ public static final Double DEFAULT_DOUBLE = 0.0d; /** <P>Get an object containing an initialized value for the static class-type.</P> @param cls_static May not be {@code null}. @return <CODE>{@link getForClassName(String) getForClassName}(cls_static.getName())</CODE> **/ public static final Object getForClass(Class cls_static) { try { return getForClassName(cls_static.getName()); } catch(RuntimeException rtx) { throw new NullPointerException("getForClass: cls_static"); } } /** <P>Get an object containing an initialized value for the type whose name is in a string.</P> <P>Idea from (viewed 1/2/2014) <BR> &nbsp; &nbsp; {@code <A HREF="https://stackoverflow.com/questions/2891970/getting-default-value-for-java-primitive-types/2892067#2892067">https://stackoverflow.com/questions/2891970/getting-default-value-for-java-primitive-types/2892067#2892067</A>}</P> @param s_type May not be {@code null}. @return If {@code s_type} is equal to<UL> <LI>{@code "boolean"}: {@link #DEFAULT_BOOLEAN}</LI> <LI>{@code "char"}: {@link #DEFAULT_CHAR}</LI> <LI>{@code "byte"}: {@link #DEFAULT_BYTE}</LI> <LI>{@code "short"}: {@link #DEFAULT_SHORT}</LI> <LI>{@code "int"}: {@link #DEFAULT_INT}</LI> <LI>{@code "long"}: {@link #DEFAULT_LONG}</LI> <LI>{@code "float"}: {@link #DEFAULT_FLOAT}</LI> <LI>{@code "double"}: {@link #DEFAULT_DOUBLE}</LI> <LI><I>anything else</I>: {@code null}</LI> </UL> @see #getForClass(Class) getForClass(cls) **/ public static final Object getForClassName(String s_type) { try { if(s_type.equals("boolean")) { return DEFAULT_BOOLEAN; } } catch(NullPointerException npx) { throw new NullPointerException("getForClassName: s_type"); } if(s_type.equals("char")) { return DEFAULT_CHAR; } if(s_type.equals("byte")) { return DEFAULT_BYTE; } if(s_type.equals("short")) { return DEFAULT_SHORT; } if(s_type.equals("int")) { return DEFAULT_INT; } if(s_type.equals("long")) { return DEFAULT_LONG; } if(s_type.equals("float")) { return DEFAULT_FLOAT; } if(s_type.equals("double")) { return DEFAULT_DOUBLE; } //Non-primitive type return null; } }

Tengo un tipo primitivo Java a mano:

Class c = int.class; // or long.class, or boolean.class

Me gustaría obtener un ''valor predeterminado'' para esta clase; específicamente, el valor se asigna a campos de este tipo si no se inicializan. Por ejemplo, ''0'' para un número, ''falso'' para un booleano.

¿Hay una manera genérica de hacer esto? Lo intenté

c.newInstance()

Pero recibo una InstantiationException y no una instancia predeterminada.


Es posible obtener el valor predeterminado de cualquier tipo creando una matriz de un elemento y recuperando su primer valor.

private static <T> T getDefaultValue(Class<T> clazz) { return (T) Array.get(Array.newInstance(clazz, 1), 0); }

De esta forma, no es necesario tener en cuenta todos los tipos primitivos posibles, a un costo generalmente despreciable de crear una matriz de un elemento.


Esto es lo que estoy pensando (sin embargo, falla la prueba de elegancia):

public class PrimitiveDefaults { // These gets initialized to their default values private static boolean DEFAULT_BOOLEAN; private static byte DEFAULT_BYTE; private static short DEFAULT_SHORT; private static int DEFAULT_INT; private static long DEFAULT_LONG; private static float DEFAULT_FLOAT; private static double DEFAULT_DOUBLE; public static Object getDefaultValue(Class clazz) { if (clazz.equals(boolean.class)) { return DEFAULT_BOOLEAN; } else if (clazz.equals(byte.class)) { return DEFAULT_BYTE; } else if (clazz.equals(short.class)) { return DEFAULT_SHORT; } else if (clazz.equals(int.class)) { return DEFAULT_INT; } else if (clazz.equals(long.class)) { return DEFAULT_LONG; } else if (clazz.equals(float.class)) { return DEFAULT_FLOAT; } else if (clazz.equals(double.class)) { return DEFAULT_DOUBLE; } else { throw new IllegalArgumentException( "Class type " + clazz + " not supported"); } } }



Las variables de clase de primitivas no necesitan ser inicializadas o configuradas con un valor predeterminado. Sin embargo, las variables declaradas en otro ámbito deben inicializarse o obtendrá errores de compilación.

public class PrimitiveStuff { private int aInt; private long aLong; private boolean aBoolean; public PrimitiveStuff() { System.out.println("aInt : " + aInt); //prints 0 System.out.println("aLong: "+ aLong);//prints 0 System.out.println("aBoolean: " + aBoolean);//prints false } public void doStuff(){ int outherInt; System.out.println(outherInt); //will not compile } public static void main(String[] args) { new PrimitiveStuff(); }

}


No hay una manera elegante de hacer esto. De hecho, ni siquiera es posible declarar la firma de un método que devolverá los valores primitivos per se.

Lo más cercano que puedes venir es algo como esto:

public Object defaultValue(Class cls) { if (class == Boolean.TYPE) { return Boolean.FALSE; } else if (class == Byte.TYPE) { return Byte.valueOf(0); } else if (class == Short.TYPE) { ... } else { return null; } }


Puedes hacer esto con la reflexión, pero es más fácil y claro escribirlo, por ejemplo

Object defaultValue(Class cls) { Map defaults = new HashMap(); defaults.put(Integer.TYPE, Integer.valueOf(0)); defaults.put(Double.TYPE, Double.valueOf(0)); defaults.put(Boolean.TYPE, Boolean.FALSE); //... etc return defaults.get(cls); }

Por supuesto, es probable que desee mover la inicialización del mapa a un constructor o similar para la inicialización de una sola vez.

Razonablemente conciso, ¿es elegante?


Una alternativa a Guava''s Defaults.java , que permite a la implementación descubrir los valores predeterminados (mejorados al usar la respuesta de Antag99 ):

import static java.util.stream.Collectors.toMap; import java.lang.reflect.Array; import java.util.Map; import java.util.stream.Stream; public class DefaultValue { /** * @param clazz * the class for which a default value is needed * @return A reasonable default value for the given class (the boxed default * value for primitives, <code>null</code> otherwise). */ @SuppressWarnings("unchecked") public static <T> T forClass(Class<T> clazz) { return (T) DEFAULT_VALUES.get(clazz); } private static final Map<Class<?>, Object> DEFAULT_VALUES = Stream .of(boolean.class, byte.class, char.class, double.class, float.class, int.class, long.class, short.class) .collect(toMap(clazz -> (Class<?>) clazz, clazz -> Array.get(Array.newInstance(clazz, 1), 0))); public static void main(String... args) { System.out.println(DefaultValue.forClass(int.class)); // 0 System.out.println(DefaultValue.forClass(Integer.class)); // null } }