convert value to given type via Reflection - Android java.lang.reflect

Android examples for java.lang.reflect:Base Type

Description

convert value to given type via Reflection

Demo Code


//package com.java2s;
import android.text.TextUtils;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Array;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

import java.util.HashSet;
import java.util.List;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class Main {
    private static final ConcurrentMap<String, Class<?>> CLASS_CACHE = new ConcurrentHashMap<>();
    /**//from   w w  w.  j  a  v a2s  .  c o m
     * default date format.
     */
    private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /**
     * convert value to given type.
     * null safe.
     *
     * @param value value for convert
     * @param type  will converted type
     * @return value while converted
     */
    public static Object convertCompatibleType(Object value, Class<?> type) {

        if (value == null || type == null
                || type.isAssignableFrom(value.getClass())) {
            return value;
        }
        if (value instanceof String) {
            String string = (String) value;
            if (char.class.equals(type) || Character.class.equals(type)) {
                if (string.length() != 1) {
                    throw new IllegalArgumentException(
                            String.format(
                                    "CAN NOT convert String(%s) to char!"
                                            + " when convert String to char, the String MUST only 1 char.",
                                    string));
                }
                return string.charAt(0);
            } else if (type.isEnum()) {
                return Enum.valueOf((Class<Enum>) type, string);
            } else if (type == BigInteger.class) {
                return new BigInteger(string);
            } else if (type == BigDecimal.class) {
                return new BigDecimal(string);
            } else if (type == Short.class || type == short.class) {
                return Short.valueOf(string);
            } else if (type == Integer.class || type == int.class) {
                return Integer.valueOf(string);
            } else if (type == Long.class || type == long.class) {
                return Long.valueOf(string);
            } else if (type == Double.class || type == double.class) {
                return Double.valueOf(string);
            } else if (type == Float.class || type == float.class) {
                return Float.valueOf(string);
            } else if (type == Byte.class || type == byte.class) {
                return Byte.valueOf(string);
            } else if (type == Boolean.class || type == boolean.class) {
                return Boolean.valueOf(string);
            } else if (type == Date.class) {
                try {
                    return new SimpleDateFormat(DATE_FORMAT)
                            .parse((String) value);
                } catch (ParseException e) {
                    throw new IllegalStateException("Failed to parse date "
                            + value + " by format " + DATE_FORMAT
                            + ", cause: " + e.getMessage(), e);
                }
            } else if (type == Class.class) {
                return forName((String) value);
            }
        } else if (value instanceof Number) {
            Number number = (Number) value;
            if (type == byte.class || type == Byte.class) {
                return number.byteValue();
            } else if (type == short.class || type == Short.class) {
                return number.shortValue();
            } else if (type == int.class || type == Integer.class) {
                return number.intValue();
            } else if (type == long.class || type == Long.class) {
                return number.longValue();
            } else if (type == float.class || type == Float.class) {
                return number.floatValue();
            } else if (type == double.class || type == Double.class) {
                return number.doubleValue();
            } else if (type == BigInteger.class) {
                return BigInteger.valueOf(number.longValue());
            } else if (type == BigDecimal.class) {
                return BigDecimal.valueOf(number.doubleValue());
            } else if (type == Date.class) {
                return new Date(number.longValue());
            }
        } else if (value instanceof Collection) {
            Collection collection = (Collection) value;
            if (type.isArray()) {
                int length = collection.size();
                Object array = Array.newInstance(type.getComponentType(),
                        length);
                int i = 0;
                for (Object item : collection) {
                    Array.set(array, i++, item);
                }
                return array;
            } else if (!type.isInterface()) {
                try {
                    Collection result = (Collection) type.newInstance();
                    result.addAll(collection);
                    return result;
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            } else if (type == List.class) {
                return new ArrayList<>(collection);
            } else if (type == Set.class) {
                return new HashSet<>(collection);
            }
        } else if (value.getClass().isArray()
                && Collection.class.isAssignableFrom(type)) {
            Collection collection;
            if (!type.isInterface()) {
                try {
                    collection = (Collection) type.newInstance();
                } catch (Throwable e) {
                    collection = new ArrayList<>();
                }
            } else if (type == Set.class) {
                collection = new HashSet<>();
            } else {
                collection = new ArrayList<>();
            }
            int length = Array.getLength(value);
            for (int i = 0; i < length; i++) {
                collection.add(Array.get(value, i));
            }
            return collection;
        }
        return value;
    }

    /**
     * Returns a {@code Class} object which represents the class with
     * the given name. The name should be the name of a non-primitive
     * class, as described in the {@link Class class definition}.
     * Primitive types can not be found using this method; use {@code
     * int.class} or {@code Integer.TYPE} instead.
     *
     * @param packages  class package
     * @param className given class name
     * @return
     */
    public static Class<?> forName(String[] packages, String className) {
        if (packages != null && packages.length > 0
                && !className.contains(".")
                && !CLASS_CACHE.containsKey(className)) {
            for (String pkg : packages) {
                try {
                    return _forName(pkg + "." + className);
                } catch (ClassNotFoundException e2) {
                }
            }
            try {
                return _forName("java.lang." + className);
            } catch (ClassNotFoundException e2) {
            }
        }
        try {
            return _forName(className);
        } catch (ClassNotFoundException e) {
            int index = className.lastIndexOf('.');
            if (index > 0 && index < className.length() - 1) {
                try {
                    return _forName(className.substring(0, index) + "$"
                            + className.substring(index + 1));
                } catch (ClassNotFoundException e2) {
                }
            }
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    /**
     * Returns a {@code Class} object which represents the class with
     * the given name. The name should be the name of a non-primitive
     * class, as described in the {@link Class class definition}.
     * Primitive types can not be found using this method; use {@code
     * int.class} or {@code Integer.TYPE} instead.
     *
     * @param className
     * @return
     */
    public static Class<?> forName(String className) {
        try {
            return _forName(className);
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    /**
     * New instance for the given class name.{@link #forName(String)}
     *
     * @param className
     * @return
     */
    public static Object newInstance(String className) {
        try {
            return forName(className).newInstance();
        } catch (InstantiationException e) {
            throw new IllegalStateException(e.getMessage(), e);
        } catch (IllegalAccessException e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }

    /**
     * Returns a {@code Class} object which represents the class with
     * the given name. The name should be the name of a non-primitive
     * class, as described in the {@link Class class definition}.
     * Primitive types can not be found using this method; use {@code
     * int.class} or {@code Integer.TYPE} instead.
     * <p/>
     * also support for array, like int[][].
     *
     * @param name
     * @return
     * @throws ClassNotFoundException
     */
    private static Class<?> _forName(String name)
            throws ClassNotFoundException {
        if (TextUtils.isEmpty(name)) {
            return null;
        }
        String key = name;
        Class<?> clazz = CLASS_CACHE.get(key);
        if (clazz == null) {
            int index = name.indexOf('[');
            if (index > 0) {
                int i = (name.length() - index) / 2;
                name = name.substring(0, index);
                StringBuilder sb = new StringBuilder();
                while (i-- > 0) {
                    sb.append("[");
                }
                if ("void".equals(name)) {
                    sb.append("V");
                } else if ("boolean".equals(name)) {
                    sb.append("Z");
                } else if ("byte".equals(name)) {
                    sb.append("B");
                } else if ("char".equals(name)) {
                    sb.append("C");
                } else if ("double".equals(name)) {
                    sb.append("D");
                } else if ("float".equals(name)) {
                    sb.append("F");
                } else if ("int".equals(name)) {
                    sb.append("I");
                } else if ("long".equals(name)) {
                    sb.append("J");
                } else if ("short".equals(name)) {
                    sb.append("S");
                } else {
                    sb.append('L').append(name).append(';');
                }
                name = sb.toString();
            }
            try {
                clazz = Class.forName(name, true, Thread.currentThread()
                        .getContextClassLoader());
            } catch (ClassNotFoundException cne) {
                clazz = Class.forName(name);
            }
            Class<?> old = CLASS_CACHE.putIfAbsent(key, clazz);
            if (old != null) {
                clazz = old;
            }
        }
        return clazz;
    }

    /**
     * make throwable to string.
     */
    public static String toString(Throwable throwable) {
        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);
        printWriter.print(throwable.getClass().getName() + ": ");
        if (throwable.getMessage() != null) {
            printWriter.print(throwable.getMessage() + "\n");
        }
        printWriter.println();
        try {
            throwable.printStackTrace(printWriter);
            return stringWriter.toString();
        } finally {
            printWriter.close();
        }
    }
}

Related Tutorials