java.lang.Class and java.lang.Object

4

这里有一个概念上的困难 - 从书中阅读和学习Java。

它提到了以下内容(在解释几个不同主题的过程中) -

  1. Java在类层次结构中不支持多重继承。因此,如果类C是类A的子类,则它不能同时是类B的子类(我知道接口在这里有解决方案)

  2. java.lang.Object是所有类(系统和用户)“扩展”的原始类。因此,每个类都是类java.lang.Object的直接或间接子类

  3. Java中的类不仅是编译器工件 - 在运行时,它们由类java.lang.Class的实例表示

难道#3的意思是语言本身定义的类是java.lang.Class类型的 - 而#2的意思是它们也是java.lang.Object类型的 - 与#1相矛盾?哪个类是Java类的父类?

如果#1仍然有效,我猜想这意味着#3只是说类的“运行时表示”是类java.lang.Class的实例 - 它是java.lang.Object的子类?但是类本身是java.lang.Object的子类吗?

感谢您的指导!提前致谢!


你混淆了类和类的实例。一个Class类的一个实例,而Class类像所有类一样,是Object的子类。例如,String的一个实例不是Class的实例,也不是Class的子类。只是String类本身是Class的一个实例(而不是String的实例)。 - Hot Licks
2
要真正让你大开眼界,考虑一下Class类本身就是Class的一个实例,而且,Object类也是Class的一个实例。 - Hot Licks
哦,Class<Class> clazz = Class.class 可以运行。现在我真的很困惑。 - Unihedron
3个回答

2
“#3”不是指语言本身定义的类都属于java.lang.Class类型吗?
不是的。(Class) testclass是语法错误,没有类是java.lang.Class的子类,因为它是final的。 Class扩展了Object并表示一个class
假设我有一个默认继承ObjectTestClass,现在TestClass.class(TestClass).getClass()存在,它们返回Class<TestClass>,它扩展了Object并且是Class的实例。
但是,如果您查看Java文档中的Class,您会发现它们不仅仅是Object

谢谢!我明白了 - 只是觉得类是对象的子类型有点奇怪 - 但一旦理解了,就确实很合理。 - Bi Act

2
Java中的类不仅仅是编译器生成的产物,而且在运行时,它们由类 java.lang.Class 的实例表示。这是正确的。这是否意味着语言本身定义的类属于 java.lang.Class 类型?这是正确的。而 #2 意味着它们也属于 java.lang.Object 类型。这也是正确的。这是否与 #1 矛盾?这是不正确的。没有矛盾。"extends" 关系仅在类之间以及在表示运行时类的 Class 对象之间定义。如果您查看 java.lang.Class API,您将看到像 Class getSuperclass()isAssignableFrom(Class) 这样的方法...尽管 isAssignableFrom 在测试 "subtype" 关系。请注意,这些方法接受另一个 Class 作为参数或返回另一个 Class。类和实例之间没有 "inherits" 或 "extends" 关系。运行时对象之间也不存在这样的关系。java.lang.Class 扩展 java.lang.Object 的事实在这里并不相关。如果 #1 仍然成立,那么我想这意味着 #3 只是说类的 "运行时表示" 是 java.lang.Class 类的实例 - 它是 java.lang.Object 的子类吗?这是正确的。但要注意的是,这两个属性不是直接相互关联的。类和表示类的运行时类之间存在类似的关系,这是(某种程度上)巧合的。

1

3) Java中的类不仅仅是编译器生成的工件 - 在运行时,它们由类java.lang.Class的实例表示

这是不正确的。Java对象是 对象。它们还有一个代表它们的类类型的 属性

public class Test  {
   public static final void main(String[] ignored)  {
      String s = "x";
      Class cls = s.getClass();
      System.out.println("s=" + s.toString());
      System.out.println("cls=" + cls.toString());  
   }
}

输出:

s=x
cls=class java.lang.String

我们说“Java对象是类”有些令人困惑。一般来说确实如此,但是在这个具体的技术细节上,这种说法是不准确的。

粗略地说,Java对象存储在*.class文件中,这也是使这种区分变得混淆的另一件事。


如果它们被存储在 *.object 文件中,会不会更清晰易懂? - Hot Licks
@HotLicks 嗯,我不太明白。您是在暗示我的回答有待改进吗? - aliteralmind
实际上,我认为 *.class 存储了一个 Java classanonymous class 或者一个 inner class。Java 对象除非被序列化,否则存储在堆中。 - Unihedron
2
@HotLicks,把我当成你的笑话对象是非常低级的行为。 ;) - aliteralmind
2
我能说什么呢?我是个老的汇编语言程序员,根本没有什么面向对象的思想。 - Hot Licks
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接