Динамично найдите класс, который представляет примитивный тип Java

Компонент GNU ld - это так называемый интеллектуальный компоновщик. Он будет отслеживать функции, используемые предыдущими статическими библиотеками, постоянно отбрасывая те функции, которые не используются из его таблиц поиска. В результате, если вы связали статическую библиотеку слишком рано, то функции в этой библиотеке больше не будут доступны для статических библиотек позже в линии ссылок.

Типичный компоновщик UNIX работает слева направо, поэтому поместите все ваши зависимые библиотеки слева и те, которые удовлетворяют этим зависимостям справа от линии ссылки. Вы можете обнаружить, что некоторые библиотеки зависят от других, в то время как другие библиотеки зависят от них. Здесь все усложняется. Когда дело доходит до круговых ссылок, исправьте свой код!

46
задан Mike Furtak 8 October 2008 в 14:00
поделиться

5 ответов

Платформа Spring содержит служебный класс ClassUtils , который содержит статический метод forName. Этот метод может использоваться для точной цели, которую Вы описали.

В случае, если Вам don’t нравится иметь зависимость от Spring: исходный код метода может быть найден e. В g. здесь на их общедоступном репозитории. Исходный код класса лицензируется под моделью Apache 2.0.

Примечание однако, что алгоритм использует трудно кодированную карту типов примитивов.

<час>

Редактирование: Благодаря DГЎvid HorvГЎth комментаторов и Patrick для указания на неработающую ссылку.

21
ответ дан Synoli 8 November 2019 в 00:16
поделиться

Эти Class экземпляры для типов примитивов доступны, поскольку Вы сказали использование, например, int.class, но также возможно получить те же значения с помощью чего-то как Integer.TYPE. Каждый примитивный класс обертки содержит статическое поле, TYPE, который имеет соответствующий примитивный экземпляр класса.

Вы не можете получить примитивный класс через forName, но можно получить его от класса, который легко доступен. Если абсолютно необходимо использовать отражение, можно попробовать что-то вроде этого:

Class clazz = Class.forName("java.lang.Integer");
Class intClass = clazz.getField("TYPE").get(null);

intClass.equals(int.class);         // => true
26
ответ дан Daniel Spiewak 8 November 2019 в 00:16
поделиться

Вероятно, просто необходимо отобразить примитивы, и для остальной части классов выполняют "forName" метод:

я сделал бы что-то как:

void someWhere(){
     String methodDescription = "doSomething int double java.lang.Integer java.lang.String"
     String [] parts = methodDescription.split();
     String methodName= parts[0]
     Class [] paramsTypes = getParamTypes( parts ); // Well, not all the array, but a, sub array from 1 to arr.length..  

    Method m = someObject.class.getMethod( methodName, paramTypes );
    etc. etc etc.
}

public Class[] paramTypes( String [] array ){
     List<Class> list = new ArrayList<Class>();
     for( String type : array ) {
         if( builtInMap.contains( type )) {
             list.add( builtInMap.get( type ) );
          }else{
             list.add( Class.forName( type ) );
          }
     }
     return list.toArray();
}  

    // That's right.
Map<String,Class> builtInMap = new HashMap<String,Class>();{
       builtInMap.put("int", Integer.TYPE );
       builtInMap.put("long", Long.TYPE );
       builtInMap.put("double", Double.TYPE );
       builtInMap.put("float", Float.TYPE );
       builtInMap.put("bool", Boolean.TYPE );
       builtInMap.put("char", Character.TYPE );
       builtInMap.put("byte", Byte.TYPE );
       builtInMap.put("void", Void.TYPE );
       builtInMap.put("short", Short.TYPE );
}

таким образом, создайте карту, где типы примитивов хранятся и если описание принадлежит примитиву, тогда используют отображенный класс. Эта карта может также быть загружена из внешнего конфигурационного файла, для добавления гибкости, таким образом, Вы добавляете Строку как встроенный вместо java.lang. Строка или потенциально имеет метод как это.

"doSomething представляют yes|no в виде строки"

существует много этого вида кода в проектах ОС как Struts, В спящем режиме, Spring и Apache освобождают (только для упоминания некоторых), таким образом, Вы не должны запускать с нуля.

BTW. Я не скомпилировал вышеупомянутый код, но я вполне уверен, он работает с небольшими модификациями, вниз не голосуют за меня за это.

18
ответ дан Community 8 November 2019 в 00:16
поделиться

Много Методов класса не обрабатывают примитивы последовательным способом, к сожалению. Распространенный способ вокруг этого в forName состоит в том, чтобы иметь таблицу как;

private static final Map<String, Class> BUILT_IN_MAP = 
    new ConcurrentHashMap<String, Class>();

static {
    for (Class c : new Class[]{void.class, boolean.class, byte.class, char.class,  
            short.class, int.class, float.class, double.class, long.class})
        BUILT_IN_MAP.put(c.getName(), c);
}

public static Class forName(String name) throws ClassNotFoundException {
    Class c = BUILT_IN_MAP.get(name);
    if (c == null)
        // assumes you have only one class loader!
        BUILT_IN_MAP.put(name, c = Class.forName(name));
    return c;
}
3
ответ дан Peter Lawrey 8 November 2019 в 00:16
поделиться

Можно использовать этот код :)

/**
 * Get an array class of the given class.
 *
 * @param klass to get an array class of
 * @param <C>   the targeted class
 * @return an array class of the given class
 */
public static <C> Class<C[]> arrayClass(Class<C> klass) {
    return (Class<C[]>) Array.newInstance(klass, 0).getClass();
}

/**
 * Get the class that extends {@link Object} that represent the given class.
 *
 * @param klass to get the object class of
 * @return the class that extends Object class and represent the given class
 */
public static Class<?> objectiveClass(Class<?> klass) {
    Class<?> component = klass.getComponentType();
    if (component != null) {
        if (component.isPrimitive() || component.isArray())
            return Reflect.arrayClass(Reflect.objectiveClass(component));
    } else if (klass.isPrimitive()) {
        if (klass == char.class)
            return Character.class;
        if (klass == int.class)
            return Integer.class;
        if (klass == boolean.class)
            return Boolean.class;
        if (klass == byte.class)
            return Byte.class;
        if (klass == double.class)
            return Double.class;
        if (klass == float.class)
            return Float.class;
        if (klass == long.class)
            return Long.class;
        if (klass == short.class)
            return Short.class;
    }

    return klass;
}

/**
 * Get the class that don't extends {@link Object} from the given class.
 *
 * @param klass to get the non-object class of
 * @return the non-object class of the given class
 * @throws IllegalArgumentException when the given class don't have a primitive type
 */
public static Class<?> primitiveClass(Class<?> klass) {
    if (klass == Character.class)
        return char.class;
    if (klass == Integer.class)
        return int.class;
    if (klass == Boolean.class)
        return boolean.class;
    if (klass == Byte.class)
        return byte.class;
    if (klass == Double.class)
        return double.class;
    if (klass == Float.class)
        return float.class;
    if (klass == Long.class)
        return long.class;
    if (klass == Short.class)
        return short.class;

    throw new IllegalArgumentException(klass + " don't have a primitive type");
}
0
ответ дан 26 November 2019 в 20:31
поделиться
Другие вопросы по тегам:

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