Java 中的 getClass 是如何工作的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32919106/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does getClass in Java work
提问by Number945
Here is what JavaDocsays:
这是JavaDoc所说的:
public final Class <?> getClass()
Returns the runtime class of this
Object
. The returnedClass
object is the object that is locked bystatic synchronized
methods of the represented class.
The actual result type isClass<? extends |X|>
where|X|
is the erasure of the static type of the expression on whichgetClass
is called.For example, no cast is required in this code fragment:Number n = 0; Class<? extends Number> c = n.getClass();
Returns:
The Class object that represents the runtime class of this object.
public final Class <?> getClass()
返回 this 的运行时类
Object
。返回Class
的对象是被static synchronized
表示类的方法锁定的对象。
实际的结果类型是Class<? extends |X|>
在哪里被调用|X|
的表达式的静态类型的擦除getClass
。例如,此代码片段中不需要强制转换:Number n = 0; Class<? extends Number> c = n.getClass();
返回:
表示此对象的运行时类的 Class 对象。
Now , I understand it is a native method , so it is is implemented in platform-dependent code. But what about the return type of this method.
现在,我明白它是一个本地方法,所以它是在依赖于平台的代码中实现的。但是这个方法的返回类型呢。
public final Class<?> getClass()
Also , consider the code:
另外,请考虑以下代码:
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());
}
}
Output:
输出:
class Dog
类狗
So, my query lies in :
所以,我的查询在于:
- Return type of this method
- toString method is not called . A similar post on this topic is : Java. getClass() returns a class, how come I can get a string too?
- The commented code which otherwise give compile time error.
- 此方法的返回类型
- 不调用 toString 方法。关于此主题的类似帖子是: Java。getClass() 返回一个类,我怎么也能得到一个字符串?
- 否则会导致编译时错误的注释代码。
采纳答案by laune
The data for each object contains a reference to an object of class java.lang.Class, and this is returned by the method getClass. There is also one java.lang.Class object describing java.lang.Class.
每个对象的数据都包含对 java.lang.Class 类对象的引用,该引用由方法 getClass 返回。还有一个 java.lang.Class 对象描述 java.lang.Class。
Think of a Class object as the "blueprint" describing a certain class from which objects are being made. It stands to reason that blueprints also need a blueprint of their own (or else how would engineers know how to make blueprints).
可以将 Class 对象视为描述从中生成对象的某个类的“蓝图”。按道理,蓝图也需要自己的蓝图(否则工程师怎么知道如何制作蓝图)。
These statements try to illustrate this.
这些陈述试图说明这一点。
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 );
Output:
输出:
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
A class has a name, just like anything described by a blueprint has a name which is not to be confused with the blueprint itself. If a class object appears in a certain context, its toString() method is called implicitly, and this returns the class' name. If you'd like to print all the nitty-gritty details of a class (akin to printing the blueprint itself) you'd have to write a lot of code - just look at the javadoc for java.lang.Class: there's an awful lot of information to be retrieved (as befits a blueprint).
一个类有一个名称,就像蓝图描述的任何东西都有一个名称,不要与蓝图本身混淆。如果类对象出现在某个上下文中,则隐式调用其 toString() 方法,并返回类的名称。如果你想打印一个类的所有细节(类似于打印蓝图本身),你必须编写大量代码 - 只需查看 java.lang.Class 的 javadoc:有一个可怕的要检索的大量信息(适合蓝图)。
回答by deepak marathe
At this point, we need to differentiate between a type
and an instance
of the type. Lets explain it with an example.
此时,我们需要区分类型的atype
和 an instance
。让我们用一个例子来解释它。
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`
}
}
Type
类型
The reference 'typeInformation' in the above code is of the type Class
keeping aside the generics for a while. This information will typically be residing in non-heap memory section. Following information is store against each of the type
jvm loads :
上面代码中的引用“typeInformation”属于Class
将泛型放在一边的类型。此信息通常驻留在非堆内存部分。以下信息针对每个type
jvm 负载存储:
- The fully qualified name of the type
- The fully qualified name of the type's direct superclass (unless the type is an interface or class java.lang.Object, neither of which have a superclass)
- Whether or not the type is a class or an interface
- The type's modifiers ( some subset of` public, abstract, final)
- An ordered list of the fully qualified names of any direct superinterfaces
- 类型的完全限定名称
- 类型的直接超类的完全限定名称(除非类型是接口或类 java.lang.Object,两者都没有超类)
- 类型是类还是接口
- 类型的修饰符(public、abstract、final的一些子集)
- 任何直接超级接口的完全限定名称的有序列表
Instance
实例
instaneOfA is a reference to the actual instance of the type A
which points to an address in the heap memory.
instaneOfA 是对A
指向堆内存中地址的类型的实际实例的引用。
Return type of getClass() is a generic Class
type. Like many other type
s available in java - String, Integer etc, Class is also a type representing the type information associated.
getClass() 的返回类型是泛型Class
类型。与type
java 中可用的许多其他类型 - String、Integer 等一样,Class 也是一种表示相关类型信息的类型。
toString() method is associated and invoked on an instance
of the Dog class, not on the Dog type itself.
toString() 方法instance
在 Dog 类的一个上关联和调用,而不是在 Dog 类型本身上。
//Class<Dog> dd = new Dog(); Compile time error
//Class<Dog> dd = new Dog(); Compile time error
This is due to Type mismatch occuring while assigning the result of expression in the right hand side to the Left Hand Side, which is not of the same type. Class dd refers to a reference of Class type. Dog is a different type altogether, and a new Dog() can be assigned to a reference of the type 'Dog'.
这是由于在将右侧的表达式结果分配给左侧(不是同一类型)时发生了类型不匹配。dd 类指的是 Class 类型的引用。Dog 是完全不同的类型,可以将 new Dog() 分配给类型为“Dog”的引用。
This link will help you understand the design aspects of java runtime environment
回答by Hasitha Solasa
I have an answer for your Question 3,
我对你的问题 3 有一个答案,
This gives compile time error because
这会导致编译时错误,因为
Reason 1: For a Class instance, You can only assign class object that represents the Dog class, but you can't assign the Dog class object directly.
原因一:对于Class实例,只能赋值代表Dog类的类对象,不能直接赋值Dog类对象。
For example: Class dd=Dog.class or Class dd=Class.forName("Dog"); is correct syntax.
例如:Class dd=Dog.class 或 Class dd=Class.forName("Dog"); 是正确的语法。
Reason 2: The class Class is a final class but not a super class for Dog class. You go back to the concept of dynamic method dispatch in java,where you can only assign subclass objects to a superclass variable.
原因2:Class类是final类,但不是Dog类的超类。你回到java中动态方法调度的概念,你只能将子类对象分配给超类变量。