Получение значения по умолчанию для типов примитивов

У меня есть тип примитива Java под рукой:

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

Я хотел бы получить значение по умолчанию для этого класса - а именно, значение присвоено полям этого типа, если они не инициализируются. Например, 0 для числа, false для булевской переменной.

Существует ли универсальный способ сделать это? Я попробовал это:

c.newInstance()

Но я добираюсь InstantiationException, и не экземпляр по умолчанию.

49
задан Lii 16 January 2019 в 04:32
поделиться

5 ответов

В библиотеках Guava это уже есть:
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
52
ответ дан 7 November 2019 в 11:42
поделиться

Нет элегантного способа сделать это. Фактически, невозможно даже объявить сигнатуру метода, который будет возвращать примитивные значения как таковые.

Ближайшее, что вы можете подойти, выглядит примерно так:

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;
    }
}
1
ответ дан 7 November 2019 в 11:42
поделиться

Переменные класса примитивов не нужно инициализировать или устанавливать со значением по умолчанию. Однако переменные, объявленные в другой области, должны быть инициализированы, иначе вы получите ошибки компиляции.

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();
}

}

0
ответ дан 7 November 2019 в 11:42
поделиться

Вот о чем я думаю (хотя и не прошел тест на элегантность):

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");
        }
    }
}
11
ответ дан 7 November 2019 в 11:42
поделиться

Вы можете сделать это с помощью отражения, но проще и яснее всего это записать, например

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);
}

Конечно, вы, вероятно, захотите перенести инициализацию карты в конструктор или аналогичный для однократной инициализации.

Достаточно лаконично - это элегантно?

2
ответ дан 7 November 2019 в 11:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: