답변:
의 종류는 Object[]
않습니다 정말 원시적 수 없습니다 - 당신이 참조를 가지고 있기 때문에! 여기서의 유형은 i
is 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.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()
진정한 수익을
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
에 ==
. 클래스는 싱글 톤입니다.
자바의 자동 복싱을 처리해야합니다.
코드를 가져 가자
공개 수업 시험 { public static void main (String [] args) { int i = 3; 객체 o = i; 반환; } }test.class 클래스와 javap -c test를 받으면 생성 된 바이트 코드를 검사 할 수 있습니다.
"test.java"에서 컴파일 됨 공용 클래스 테스트는 java.lang.Object {를 확장합니다. 공개 테스트 (); 암호: 0 : aload_0 1 : invokespecial # 1; // 메소드 java / lang / Object. "":() V 4 : 반환보시다시피 Java 컴파일러가 추가되었습니다.public static void main (java.lang.String []); 암호: 0 : iconst_3 1 : istore_1 2 : iload_1 3 : invokestatic # 2; // Method java / lang / Integer.valueOf : (I) Ljava / lang / Integer; 6 : astore_2 7 : 반환
}
invokestatic # 2; // Method java / lang / Integer.valueOf : (I) Ljava / lang / Integer;int에서 새 Integer를 만든 다음 astore_2를 통해 o에 새 Object 를 저장 합니다.
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를 반환하는 것이 가능하다는 것을 알 수 있습니다 (거짓 이유를 보여주는 충분한 답변이 있기 때문에).
public class Main
{
public static void main(final String[] argv)
{
final Class clazz;
clazz = int.class;
System.out.println(clazz.isPrimitive());
}
}
이것은 메서드가 "Integer"가 아닌 "int"를 사용할 때 반영됩니다.
이 코드는 다음과 같이 작동합니다.
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)
{
}
}
primitve 래퍼 유형은이 값에 응답하지 않습니다. 이것은 프리미티브의 클래스 표현을위한 것이지만, 리플렉션을 제외하고는 너무 많이 사용한다고 생각할 수는 없습니다. 예를 들어
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 변형 (commons 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
javapoet 사용자에게는 다음과 같은 방법도 있습니다.
private boolean isBoxedPrimitive(Class<?> type) {
return TypeName.get(type).isBoxedPrimitive();
}
int.class.isPrimitive()
yieldstrue
;Integer.class.isPrimitive()
수익률false
.