繁体   English   中英

Java中的getClass如何工作

[英]How does getClass in Java work

以下是JavaDoc所说的内容:

 public final Class <?> getClass() 

返回此Object的运行时类。 返回的Class对象是由所表示的类的static synchronized方法锁定的对象。
实际的结果类型是Class<? extends |X|> Class<? extends |X|> where |X| 是调用getClass的表达式的静态类型的擦除。 例如,此代码片段中不需要强制转换:

 Number n = 0; Class<? extends Number> c = n.getClass(); 

返回:
Class对象,表示此对象的运行时类。

现在,我知道它是一个本机方法,因此它是在依赖于平台的代码中实现的。 但是这种方法的返回类型呢?

public final Class<?> getClass()

另外,请考虑以下代码:

class Dog
{
    @Override
    public String toString()
    {
        return "cat";
    }
}

public class Main
{
    public static void main(String[] args)
    {
        Dog d= new Dog();
        //Class<Dog> dd = new Dog();  Compile time error
        System.out.println(d.getClass());
    }
}

输出:

班狗

所以,我的疑问在于:

  1. 返回此方法的类型
  2. 不调用toString方法。 关于这个主题的类似帖子是: Java。 getClass()返回一个类,为什么我也能得到一个字符串呢?
  3. 注释的代码否则会产生编译时错误。

每个对象的数据包含对类java.lang.Class的对象的引用,这由方法getClass返回。 还有一个描述java.lang.Class的java.lang.Class对象。

可以将Class对象视为描述从中创建对象的特定类的“蓝图”。 按理说,蓝图也需要自己的蓝图(否则工程师将如何知道如何制作蓝图)。

这些陈述试图说明这一点。

Integer integer = 1;
Class<?> clazzInteger = integer.getClass();
System.out.println( "class of integer=" + clazzInteger );
Class<?> clazzClazzInteger = clazzInteger.getClass();
System.out.println( "class of class Integer's class=" + clazzClazzInteger );
String string = "x";
Class<?> clazzString = string.getClass();
System.out.println( "class of string=" + clazzString );
Class<?> clazzClazzString = clazzString.getClass();
System.out.println( "class of class String's class=" + clazzClazzString );

输出:

class of integer=class java.lang.Integer
class of class Integer's class=class java.lang.Class
class of string=class java.lang.String
class of class String's class=class java.lang.Class

类有一个名称,就像蓝图描述的任何名称一样,不要与蓝图本身混淆。 如果类对象出现在某个上下文中,则会隐式调用其toString()方法,并返回类的名称 如果您想要打印类的所有细节(类似于打印蓝图本身),您必须编写大量代码 - 只需查看java.lang.Class的javadoc:有一个糟糕的要检索的大量信息(如蓝图所示)。

此时,我们需要区分typetypeinstance 让我们用一个例子来解释它。

    public class A {
        public static void main(String[] args) {
            Class<A> typeInformation = A.class; //Type information associated with type `A`
            A instanceOfA = new A();  //actual instance of type `A`
        }   
    }

类型

在上面的代码的参考“typeInformation”是的类型的Class保持预留泛型一会儿。 此信息通常驻留在非堆内存部分中。 针对每种type jvm加载存储以下信息:

  • 类型的完全限定名称
  • 类型的直接超类的完全限定名称(除非类型是接口或类java.lang.Object,它们都没有超类)
  • 类型是类还是接口
  • 类型的修饰符(`public,abstract,final的某个子集)
  • 任何直接超接口的完全限定名称的有序列表

instaneOfA是对类型A的实际实例的引用,它指向堆内存中的地址。

getClass()的返回类型是泛型Class类型。 与java中可用的许多其他type一样 - String,Integer等,Class也是表示相关类型信息的类型。

toString()方法在Dog类的instance上关联并调用,而不是在Dog类型本身上。

//Class<Dog> dd = new Dog(); Compile time error

这是由于在将右侧的表达式结果分配给左手侧(不是同一类型)时发生类型不匹配。 类dd指的是类类型的引用。 狗是完全不同的类型,并且可以将新的Dog()分配给“Dog”类型的引用。

此链接将帮助您了解Java运行时环境的设计方面

我对你的问题3有一个答案,

这给出了编译时错误,因为

原因1:对于Class实例,您只能分配表示Dog类的类对象,但不能直接分配Dog类对象。

例如:Class dd = Dog.class或Class dd = Class.forName(“Dog”); 是正确的语法。

原因2:类Class是最终类,但不是Dog类的超类。 您将回到java中的动态方法分派的概念,其中您只能将子类对象分配给超类变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM