拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 Java中a.getClass方法和A.class之间的区别

Java中a.getClass方法和A.class之间的区别

白鹭 - 2021-11-24 710 0 0

1.概述

在Java中,java.lang.Class是所有反射操作的入口点。一旦有了java.lang.Class对象,就可以调用相应的方法来获取反射类的对象。

在本教程中,我们将讨论两种不同的获取java.lang.Class对象的方式之间的区别:

2.两种方法的简要介绍

Object.getClass() Object类的实例方法。如果有一个对象,则可以调用object.getClass()以获取其类型Class

同样,我们可以使用ClassName.class语法获取Class对象。一个例子可以清楚地解释它:

@Test

 public void givenObjectAndType_whenGettingClassObject_thenTwoMethodsHaveTheSameResult() {

 String str = "I am an object of the String class";



 Class fromStrObject = str.getClass();

 Class clazz = String.class;



 assertSame(fromStrObject, clazz);

 }

在上面的测试方法中,我们尝试使用我们提到的两种方法String Class对象。最后,断言方法告诉我们两个Class象是同一实例。

但是,这两种方法之间存在差异。让我们仔细看看它们。

3.运行时类型与静态类型

让我们快速回顾一下前面的示例。**当我们调用str.getClass()方法时,我们将获得str对象的运行时类型。另一方面, String.class静态评估String**类。在此示例中, strString.class的运行时类型相同。

但是,如果使用了类继承,则它们可以不同。让我们看两个简单的类:

public class Animal {

 protected int numberOfEyes;

 }



 public class Monkey extends Animal {

 // monkey stuff

 }

现在,让我们实例化Animal类的对象并进行另一个测试:

@Test

 public void givenClassInheritance_whenGettingRuntimeTypeAndStaticType_thenGetDifferentResult() {

 Animal animal = new Monkey();



 Class runtimeType = animal.getClass();

 Class staticType = Animal.class;



 assertSame(staticType, runtimeType);

 }

如果我们运行上面的测试,将会导致测试失败:

java.lang.AssertionError: ....

 Expected :class com.baeldung.getclassobject.Animal

 Actual :class com.baeldung.getclassobject.Monkey

在测试方法中,即使我们通过Animal animal = new Monkey(); animal而不是Monkey animal = new Monkey(); animal对象的运行时类型仍然是Monkey.这是因为animal像在运行时Monkey的实例。

但是,当我们获得Animal类的静态类型时,该类型始终是Animal

4.处理基本类型

在编写Java代码时,我们经常使用基本类型。让我们尝试object.getClass()方法获取原始类型Class

int number = 7;

 Class numberClass = number.getClass();

如果我们尝试编译上面的代码,则会收到编译错误:

Error: java: int cannot be dereferenced

编译器不能取消引用number变量,因为它是原始变量。因此, object.getClass()方法无法帮助我们获取基本类型Class

让我们看看是否可以使用.class语法获取原始类型:

@Test

 public void givenPrimitiveType_whenGettingClassObject_thenOnlyStaticTypeWorks() {

 Class intType = int.class;

 assertNotNull(intType);

 assertEquals("int", intType.getName());

 assertTrue(intType.isPrimitive());

 }

因此,我们可以int.class int基本类型Class对象。在Java版本9和更高版本中,原始类型Class java.base模块。

如测试所示, .class语法是获取原始类型Class

5.在没有实例的情况下获取类

我们已经了解到object.getClass()方法可以为我们提供其运行时类型Class

现在,让我们考虑要获取Class对象但由于目标类是abstract类, interface,或某些类不允许实例化而无法获取目标类型的实例的情况:

public abstract class SomeAbstractClass {

 // ...

 }



 interface SomeInterface {

 // some methods ...

 }



 public class SomeUtils {

 private SomeUtils() {

 throw new RuntimeException("This Util class is not allowed to be instantiated!");

 }

 // some public static methods...

 }

在这些情况下,我们无法object.getClass()方法获取这些类型Class对象,但仍可以使用.class语法来获取它们**Class对象:**

@Test

 public void givenTypeCannotInstantiate_whenGetTypeStatically_thenGetTypesSuccefully() {

 Class interfaceType = SomeInterface.class;

 Class abstractClassType = SomeAbstractClass.class;

 Class utilClassType = SomeUtils.class;



 assertNotNull(interfaceType);

 assertTrue(interfaceType.isInterface());

 assertEquals("SomeInterface", interfaceType.getSimpleName());



 assertNotNull(abstractClassType);

 assertEquals("SomeAbstractClass", abstractClassType.getSimpleName());



 assertNotNull(utilClassType);

 assertEquals("SomeUtils", utilClassType.getSimpleName());

 }

如上面的测试所示, .class语法可以获取这些类型Class

因此,当我们想拥有Class对象,但又无法获得该类型的实例时, .class语法是可行的方法。

六,结论

在本文中,我们学习了两种获取Class对象的object.getClass()方法和.class语法。

稍后,我们讨论了两种方法之间的区别。下表可以给我们清晰的概述:

object.getClass()SomeClass.class
类对象object的运行时类型SomeClass的静态类型
原始类型-直接工作
接口,抽像类或无法实例化的类-直接工作
标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *