Java 获取原始类型的默认值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2891970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting default value for primitive types
提问by ripper234
I have a Java primitive type at hand:
我手头有一个 Java 原始类型:
Class<?> c = int.class; // or long.class, or boolean.class
I'd like to get a default valuefor this class -- specifically, the value is assigned to fields of this type if they are not initialized. E.g., 0
for a number, false
for a boolean.
我想为这个类获得一个默认值——特别是,如果未初始化,则该值被分配给这种类型的字段。例如,0
对于数字,false
对于布尔值。
Is there a generic way to do this? I tried this:
有没有通用的方法来做到这一点?我试过这个:
c.newInstance()
But I'm getting an InstantiationException
, and not a default instance.
但是我得到的是InstantiationException
, 而不是默认实例。
采纳答案by whiskeysierra
The Guava Libraries already contains that:
http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Defaults.html
Guava 库已经包含:http:
//guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/Defaults.html
Calling defaultValue
will return the default value for any primitive type (as specified by the JLS), and null for any other type.
调用defaultValue
将返回任何原始类型的默认值(由 JLS 指定),并为任何其他类型返回 null。
Use it like so:
像这样使用它:
import com.google.common.base.Defaults;
Defaults.defaultValue(Integer.TYPE); //will return 0
回答by Stephen C
There isn't an elegant way to do this. In fact, it is not even possible to declare the signature of a method that will return the primitive values per se.
没有一种优雅的方法可以做到这一点。事实上,甚至不可能声明将返回原始值本身的方法的签名。
The closest you can come is something like this:
最接近你的地方是这样的:
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;
}
}
回答by mdma
You can do this with reflection, but it's easiest and clearest to write it out, e.g.
你可以用反射来做到这一点,但写出来是最简单和最清晰的,例如
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);
}
Of course, you will probably want to move the map initialization out to a constructor or similar for once-only initialization.
当然,您可能希望将地图初始化移到构造函数或类似的构造函数中,以进行一次性初始化。
Reasonably concise - it is elegant?
相当简洁——它优雅吗?
回答by Hyman Leow
This is what I'm thinking (fails the elegance test though):
这就是我的想法(虽然没有通过优雅测试):
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");
}
}
}
回答by Kennet
Class variables of primitives do not need to be initialized or set with a default value. However variables declare in other scope must be initialized or you'll get compilation errors.
原语的类变量不需要初始化或设置默认值。但是,必须初始化在其他范围内声明的变量,否则会出现编译错误。
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();
}
}
}
回答by aliteralmind
Based on Hyman Leow's answer, I created this class:
根据Hyman 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;
}
}
回答by Julien Royer
An alternative to Guava's Defaults.java
, which lets the implementation figure out the default values (improved by using Antag99's answer):
Guava 的替代方法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
}
}
回答by Antag99
It's possible to get the default value of any type by creating an array of one element and retrieving its first value.
通过创建一个元素的数组并检索其第一个值,可以获得任何类型的默认值。
private static <T> T getDefaultValue(Class<T> clazz) {
return (T) Array.get(Array.newInstance(clazz, 1), 0);
}
This way there is not need to take account for every possible primitive type, at the usually negligible cost of creating a one-element array.
这样就不需要考虑每一种可能的原始类型,而创建单元素数组的成本通常可以忽略不计。