Java에서 a.getClass()
또는 사용 선택을 둘러싼 장단점은 무엇 A.class
입니까? 어느 쪽이든 a Class<?>
가 예상 되는 곳이면 어디에서나 사용할 수 있지만 다른 상황에서 둘 다 사용하면 성능이나 기타 미묘한 이점이있을 것이라고 생각합니다 (with Class.forName()
및 ClassLoader.loadClass()
.
Java에서 a.getClass()
또는 사용 선택을 둘러싼 장단점은 무엇 A.class
입니까? 어느 쪽이든 a Class<?>
가 예상 되는 곳이면 어디에서나 사용할 수 있지만 다른 상황에서 둘 다 사용하면 성능이나 기타 미묘한 이점이있을 것이라고 생각합니다 (with Class.forName()
및 ClassLoader.loadClass()
.
답변:
나는 그것들이 서로 다른 목적을 가지고 있고 둘 사이에 "선택"이 거의 없기 때문에 장단점 측면에서 비교하지 않을 것입니다.
a.getClass()
의 런타임 유형 을 반환합니다 a
. 즉, 당신이있는 경우 A a = new B();
다음 a.getClass()
반환합니다 B
클래스를.
A.class
A
클래스를 정적으로 평가하고 반사와 관련된 다른 목적으로 사용됩니다.
성능면 에서 측정 가능한 차이 가있을 수 있지만 결국 JVM 및 / 또는 컴파일러에 따라 다르기 때문에 이에 대해 아무 말도하지 않겠습니다.
이 게시물은 여기 에 기사로 다시 작성되었습니다 .
Class
나타내는 클래스 의 객체를 제공합니다 . A.class
java.lang.Class
A.getClass().class
?
A
클래스 인 경우 실제로 의미가 없습니다 . getClass
클래스 에는 정적 메서드 가 없습니다 .
실제로 사용할 수있는 위치에 따라 다릅니다. A.class
컴파일 타임에 작동하지만 a.getClass()
유형의 인스턴스가 필요하고 A
런타임에 작동합니다.
성능 차이도있을 수 있습니다. 하지만 A.class
그것의 실제 유형을 알고 있기 때문에 컴파일러에 의해 해결 될 수 A
, a.getClass()
실행시에 일어나는 가상 메소드 호출이다.
참고로 바이트 코드를 대상으로하는 컴파일러는 일반적으로에 대한 다음 명령어를 내 보냅니다 Integer.getClass()
.
aload_1
invokevirtual #3; //Method java/lang/Object.getClass:()Ljava/lang/Class;
다음은 다음과 같습니다 Integer.class
.
//const #3 = class #16; // java/lang/Integer
ldc_w #3; //class java/lang/Integer
전자는 일반적으로 가상 메서드 디스패치를 포함하므로 실행하는 데 더 오래 걸릴 수 있습니다. 그러나 결국 JVM에 따라 다릅니다.
아래의 예를보세요
a.getClass()!= A.class
즉 a는 A의 인스턴스가 아니라 A의 익명 하위 클래스입니다.
a.getClass()
유형 A의 인스턴스가 필요합니다.
a.getClass
클래스 / 유형의 인스턴스가 있고 정확한 유형을 얻고 싶을 때 사용 합니다. while a.class
은 사용 type
가능하고 인스턴스를 작성하려는 경우에 사용됩니다.
또한 컴파일 타임에 평가되는 getClass()
동안 인스턴스의 런타임 유형을 반환합니다 .class
.
의 성능을 고려 getClass()
하고 .class
, .class
보다 더 나은 성능을 가지고 getClass()
.
예 :
public class PerfomanceClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
long time=System.nanoTime();
Class class1="String".getClass();
class1="String".getClass();
class1="String".getClass();
class1="String".getClass();
System.out.println("time (getClass()) :"+(System.nanoTime()-time)+" ns");
long time2=System.nanoTime();
Class class2=String.class;
class2=String.class;
class2=String.class;
class2=String.class;
System.out.println("time (.class):"+(System.nanoTime()-time2)+" ns");
}
}
출력 :
time (getClass()) : 79410 ns
time (.class) : 8032 ns
추가하고 싶은 차이점이 하나 있습니다. Class 객체를받는 수퍼 클래스가있는 아래와 같이 생성자 클래스가 있다고 가정 해 보겠습니다. 서브 클래스 객체가 생성 될 때마다 서브 클래스의 클래스 객체가 수퍼 클래스에 전달되어야합니다. 생성자에서 인스턴스 메서드를 호출 할 수 없으므로 아래 코드는 컴파일되지 않습니다. 이 경우 당신은 대체하는 경우 myObject.getClass()
에 MyClass.class
. 완벽하게 실행됩니다.
Class MyClass
{
private MyClass myObject = new MyClass();
public MyClass()
{
super(myObject.getClass()); //error line compile time error
}
}
흥미롭게도 위의 예에서 언급 한 성능의 차이는 다른 이유와 관련이있는 것 같습니다. 3 개의 다른 클래스를 사용하면 평균적으로 성능이 거의 동일합니다.
import java.util.LinkedHashMap;
public class PerfomanceClass {
public static void main(String[] args) {
long time = System.nanoTime();
Class class1 = "String".getClass();
Class class11 = "Integer".getClass();
Class class111 = "LinkedHashMap".getClass();
System.out.println("time (getClass()) :" + (System.nanoTime() - time) + " ns");
long time2 = System.nanoTime();
Class class2 = String.class;
Class class22 = Integer.class;
Class class222 = LinkedHashMap.class;
System.out.println("time (.class):" + (System.nanoTime() - time2) + " ns");
} }
출력은 다음과 같습니다.
time (getClass()) :23506 ns
time (.class):23838 ns
그리고 호출 순서를 바꾸면 getClass()
더 빨라질 것입니다.
import java.util.LinkedHashMap;
public class PerfomanceClass {
public static void main(String[] args) {
long time2 = System.nanoTime();
Class class2 = LinkedHashMap.class;
System.out.println("time (.class):" + (System.nanoTime() - time2) + " ns");
long time = System.nanoTime();
Class class1 = "LinkedHashMap".getClass();
System.out.println("time (getClass()) :" + (System.nanoTime() - time) + " ns");
}}
산출:
time (.class):33108 ns
time (getClass()) :6622 ns
p.getClass()
(가) 여기서 p
개체의 인스턴스이며,이 객체의 실행시 클래스를 돌려줍니다 p
. p
컴파일 타임 오류를 일으키는 유형이 될 수 없으며 객체의 인스턴스 여야합니다.
// B extends A
A a = new B();
System.out.println(a.getClass());
//output: class B
p.class
표현입니다. 는 .class
클래스 구문이라고합니다. p
유형입니다. 클래스, 인터페이스 또는 배열의 이름 일 수 있으며 기본 유형일 수도 있습니다.
a.getClass() == B.class
.
유형이 사용 가능하고 인스턴스가있는 경우 getClass
메소드를 사용 하여 유형의 이름을 가져올 수 있습니다. 그렇지 않으면 .class
구문을 사용하십시오.
A.class.getClass()
?