Javaプリミティブ型が手元にあります:
Class<?> c = int.class; // or long.class, or boolean.class
このクラスのデフォルト値を取得したい-具体的には、値が初期化されていない場合、このタイプのフィールドに割り当てられます。例:0
は数値、false
はブール値。
これを行う一般的な方法はありますか?私はこれを試しました:
c.newInstance()
しかし、デフォルトのインスタンスではなく、InstantiationException
を取得しています。
Guava Librariesには既に以下が含まれています:
http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Defaults.html
defaultValue
を呼び出すと、(JLSで指定された)プリミティブ型のデフォルト値が返され、その他の型の場合はnullが返されます。
次のように使用します。
import com.google.common.base.Defaults;
Defaults.defaultValue(Integer.TYPE); //will return 0
1つの要素の配列を作成し、その最初の値を取得することにより、任意のタイプのデフォルト値を取得できます。
private static <T> T getDefaultValue(Class<T> clazz) {
return (T) Array.get(Array.newInstance(clazz, 1), 0);
}
この方法では、1つの要素の配列を作成するための通常無視できるコストで、考えられるすべてのプリミティブ型を考慮する必要はありません。
これは私が考えていることです(ただし、エレガンステストは失敗します):
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");
}
}
}
グアバのDefaults.Java
。これにより、実装はデフォルト値を把握できます( 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
}
}
リフレクションでこれを行うことができますが、それを記述するのが最も簡単で明確です。
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);
}
もちろん、マップの初期化をコンストラクターまたは1回限りの初期化のための同様のものに移動することをお勧めします。
合理的に簡潔-エレガントですか?
これを行うエレガントな方法はありません。実際、プリミティブ値自体を返すメソッドのシグネチャを宣言することさえできません。
一番近いのは次のようなものです。
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;
}
}
Jack Leowの答えに基づいて、このクラスを作成しました。
/**
<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> {@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;
}
}
プリミティブのクラス変数を初期化したり、デフォルト値で設定したりする必要はありません。ただし、他のスコープで宣言する変数は初期化する必要があります。そうしないと、コンパイルエラーが発生します。
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();
}
}