Answers:
中的类型Object[]
永远不会真正是原始类型-因为您有引用!这里的类型i
是,int
而引用的对象的类型o
是Integer
(由于自动装箱)。
听起来您需要确定类型是否为“原始包装”。我认为标准库中没有内置任何内容,但是编写起来很容易:
import java.util.*;
public class Test
{
public static void main(String[] args)
{
System.out.println(isWrapperType(String.class));
System.out.println(isWrapperType(Integer.class));
}
private static final Set<Class<?>> WRAPPER_TYPES = getWrapperTypes();
public static boolean isWrapperType(Class<?> clazz)
{
return WRAPPER_TYPES.contains(clazz);
}
private static Set<Class<?>> getWrapperTypes()
{
Set<Class<?>> ret = new HashSet<Class<?>>();
ret.add(Boolean.class);
ret.add(Character.class);
ret.add(Byte.class);
ret.add(Short.class);
ret.add(Integer.class);
ret.add(Long.class);
ret.add(Float.class);
ret.add(Double.class);
ret.add(Void.class);
return ret;
}
}
java.lang.<type>.TYPE
毕竟仅适用于原始包装本身。似乎我无法避免避免单独检查每种类型,这要感谢出色的解决方案。
HashSet
允许在O(1)中进行访问,而在最坏的情况下,一行if
语句或一条switch
语句需要O(包装数)。在实践中,if
对于固定数量的9个包装程序而言,语句是否可能毕竟不比基于散列的访问更快。
commons-lang ClassUtils
有相关方法。
新版本具有:
boolean isPrimitiveOrWrapped =
ClassUtils.isPrimitiveOrWrapper(object.getClass());
旧版本具有wrapperToPrimitive(clazz)
方法,该方法将返回原始对应关系。
boolean isPrimitiveOrWrapped =
clazz.isPrimitive() || ClassUtils.wrapperToPrimitive(clazz) != null;
Google的Guava库具有一个Primitives实用程序,该实用程序可检查类是否是基本体的包装类型:Primitives.isWrapperType(class)
。
Class.isPrimitive()适用于基本体
对于那些喜欢简洁代码的人。
private static final Set<Class> WRAPPER_TYPES = new HashSet(Arrays.asList(
Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class));
public static boolean isWrapperType(Class clazz) {
return WRAPPER_TYPES.contains(clazz);
}
void.class.isPrimitive()
返回true
Void
是null
;)对于创建一个Callable<Void>
不返回任何内容的Callable 很有用。
从Java 1.5及更高版本开始,有一个称为自动装箱的新功能。编译器自己执行此操作。当发现机会时,它将原始类型转换为适当的包装器类。
当您声明时,这里可能发生的事情
Object o = i;
编译器将编译此语句为:
Object o = Integer.valueOf(i);
这是自动装箱。这将解释您收到的输出。Java 1.5规范的本页详细说明了自动装箱。
Integer.valueOf(int)
本身仅在参数为“字节”时返回缓存的值(读取:-128、127 之间,包括两端)。否则调用new Integer(int)
。参见:developer.classpath.org/doc/java/lang/…、hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/…
我认为这是由于自动装箱而发生的。
int i = 3;
Object o = i;
o.getClass().getName(); // prints Integer
您可以实现与这些特定拳击类匹配的实用程序方法,并提供给您特定类是否为原始类的信息。
public static boolean isWrapperType(Class<?> clazz) {
return clazz.equals(Boolean.class) ||
clazz.equals(Integer.class) ||
clazz.equals(Character.class) ||
clazz.equals(Byte.class) ||
clazz.equals(Short.class) ||
clazz.equals(Double.class) ||
clazz.equals(Long.class) ||
clazz.equals(Float.class);
}
.equals
为==
。类是单例。
您必须处理Java的自动装箱。
让我们看一下代码
公开课测试 { 公共静态void main(String [] args) { INT我= 3; 对象o = i; 返回; } }得到类test.class和javap -c test,让我们检查生成的字节码。
从“ test.java”编译 公共类测试扩展了java.lang.Object { 公共测试(); 码: 0:加载_0 1:调用特殊#1; //方法java / lang / Object。“” :()V 4:返回如您所见,添加了Java编译器公共静态void main(java.lang.String []); 码: 0:iconst_3 1:istore_1 2:iload_1 3:invokestatic#2;//方法java / lang / Integer.valueOf:(I)Ljava / lang / Integer; 6:astore_2 7:返回
}
invokestatic#2; //方法java / lang / Integer.valueOf:(I)Ljava / lang / Integer;从您的int创建一个新的Integer,然后通过astore_2 将新的Object存储在o中
public static boolean isValidType(Class<?> retType)
{
if (retType.isPrimitive() && retType != void.class) return true;
if (Number.class.isAssignableFrom(retType)) return true;
if (AbstractCode.class.isAssignableFrom(retType)) return true;
if (Boolean.class == retType) return true;
if (Character.class == retType) return true;
if (String.class == retType) return true;
if (Date.class.isAssignableFrom(retType)) return true;
if (byte[].class.isAssignableFrom(retType)) return true;
if (Enum.class.isAssignableFrom(retType)) return true;
return false;
}
就像这样,您可以看到isPrimitive返回true是可能的(因为您有足够的答案来说明为什么它为false):
public class Main
{
public static void main(final String[] argv)
{
final Class clazz;
clazz = int.class;
System.out.println(clazz.isPrimitive());
}
}
当方法采用“ int”而不是“ Integer”时,这很重要。
此代码有效:
import java.lang.reflect.Method;
public class Main
{
public static void main(final String[] argv)
throws Exception
{
final Method method;
method = Main.class.getDeclaredMethod("foo", int.class);
}
public static void foo(final int x)
{
}
}
这段代码失败(找不到方法):
import java.lang.reflect.Method;
public class Main
{
public static void main(final String[] argv)
throws Exception
{
final Method method;
method = Main.class.getDeclaredMethod("foo", Integer.class);
}
public static void foo(final int x)
{
}
}
原始包装器类型将不响应该值。这是用于基元的类表示,尽管除了反射之外,我不能认为它有太多的用途。因此,例如
System.out.println(Integer.class.isPrimitive());
打印“ false”,但是
public static void main (String args[]) throws Exception
{
Method m = Junk.class.getMethod( "a",null);
System.out.println( m.getReturnType().isPrimitive());
}
public static int a()
{
return 1;
}
打印“ true”
我来晚了,但是如果要测试一个领域,可以使用getGenericType
:
import static org.junit.Assert.*;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import org.junit.Test;
public class PrimitiveVsObjectTest {
private static final Collection<String> PRIMITIVE_TYPES =
new HashSet<>(Arrays.asList("byte", "short", "int", "long", "float", "double", "boolean", "char"));
private static boolean isPrimitive(Type type) {
return PRIMITIVE_TYPES.contains(type.getTypeName());
}
public int i1 = 34;
public Integer i2 = 34;
@Test
public void primitive_type() throws NoSuchFieldException, SecurityException {
Field i1Field = PrimitiveVsObjectTest.class.getField("i1");
Type genericType1 = i1Field.getGenericType();
assertEquals("int", genericType1.getTypeName());
assertNotEquals("java.lang.Integer", genericType1.getTypeName());
assertTrue(isPrimitive(genericType1));
}
@Test
public void object_type() throws NoSuchFieldException, SecurityException {
Field i2Field = PrimitiveVsObjectTest.class.getField("i2");
Type genericType2 = i2Field.getGenericType();
assertEquals("java.lang.Integer", genericType2.getTypeName());
assertNotEquals("int", genericType2.getTypeName());
assertFalse(isPrimitive(genericType2));
}
}
在甲骨文的文档列出的8种原始类型。
这是我能想到的最简单的方法。包装器类仅存在于java.lang
包装中。除了包装类之外,没有其他类java.lang
具有名为的字段TYPE
。您可以使用它来检查一个类是否为Wrapper类。
public static boolean isBoxingClass(Class<?> clazz)
{
String pack = clazz.getPackage().getName();
if(!"java.lang".equals(pack))
return false;
try
{
clazz.getField("TYPE");
}
catch (NoSuchFieldException e)
{
return false;
}
return true;
}
从Spring http://static.springsource.org/spring/docs/3.0.x/javadoc-api/获取BeanUtils
Apache变体(常见的bean)可能具有类似的功能。
public class CheckPrimitve {
public static void main(String[] args) {
int i = 3;
Object o = i;
System.out.println(o.getClass().getSimpleName().equals("Integer"));
Field[] fields = o.getClass().getFields();
for(Field field:fields) {
System.out.println(field.getType());
}
}
}
Output:
true
int
int
class java.lang.Class
int
int.class.isPrimitive()
收益率true
;Integer.class.isPrimitive()
产量false
。