Java类是对象吗?

12

我之前曾经读到过Java类是Class类的实例。但现在,我的计算机科学老师说Java类不是对象。

哪一个是正确的?


当你问他的时候,他给了你什么理由? - user207421
@EJP 他说过类是一个接口,但我不记得具体内容了。 - itdoesntwork
1
Java类确实是对象,尽管是一种特殊类型的对象。例如,您可以拥有任意给定类SomeClass的多个实例:只需创建一个新的ClassLoader并重新加载“SomeClass”,您将得到相同编译时类的不同实例,可能具有不同的方法实现。 - Rogério
5个回答

22

Java类不是对象。

然而,每个Java类都有一个描述它的Class类的实例。
这些实例是对象。


1
我认为“Java类”是什么意思很重要。哪种“类”的定义不是一个对象?是带有类声明的源代码吗? - Matt Ball
所以类Class的实例与使用class关键字创建的类不是同一件事。明白了。 - itdoesntwork
@MattBall:类是一种类型,而不是对象。 - SLaks
1
那么 String.class 是什么的文字表示? - Matt Ball
它是一个对象。java.lang.Class的实例使用内存,甚至可以被垃圾回收(当通过自定义类加载器加载并最终成为垃圾时)。它们有实例字段(例如String name),以及许多实例方法。您甚至可以在运行时更改任何已加载类的方法/构造函数体的字节码,随时进行更改(某些模拟和代码覆盖工具就是这样做的,使用java.lang.instrument API)。 - Rogério

8

Java类不是对象,而是一种抽象。

但是,每个Java类都有一个相应的java.lang.Class类实例来表示它。该表示一个对象。但是你不应该将这种表示误认为是实际的东西。

这种关系有点类似于音乐和乐谱之间的关系。虽然书面符号代表音乐,但它本身并不是音乐。

然而,在实践中这种差异很少有影响,只要你知道在使用java.lang.Class对象时需要注意什么就可以了。


谢谢,这解决了我的疑惑。编辑:让我希望每种语言都像 Ruby 一样简单 :) - itdoesntwork
2
在很多方面,Ruby比Java更加复杂。 - biziclop

1

类(您的代码,甚至是 .class 文件中编译后的代码)不是对象。只有在实例化该类之后,您才拥有一个对象。

例如,Java.lang.String 是一个类。 String s = new String("Hello world"); 定义了一个 String 类型的对象。这可能是您的教授所做出的区分。


这里的“class”一词的定义很重要。 - Matt Ball
同意,这就是为什么我将我的答案指定为“类”的原因。 - Babak Naffas

1

如果一个类能够理解方法并具有自己的属性(使用“静态”),那为什么不将它们视为对象呢?对象就是这样做的。

但是这不是要向学生提出的问题,因为这只会让他们感到困惑。我认为,如果你已经掌握了类和对象的概念,那么你可以将类看作一种对象。


1
我认为静态方法并不是对象的一部分。它们似乎仅属于类。 - Scratte
@Scratte 我的意思是,当你在一个类中定义静态方法和属性时,你可以直接与类交互,而不是与类的实例交互,这就是为什么对我来说类“看起来像对象”的原因。 - Fabrizio

0
每个Java类,甚至包括java.lang.Class都是从java.lang.Object继承而来。
编辑:
措辞有点模糊。Java类的实例肯定是对象。但是仅仅类本身并不能真正被认为是对象,因为除了类的“蓝图”之外,在内存中没有任何东西存在。

1
类对象确实存在于内存中。请考虑Object.getClass()的结果。 - user207421
@EJP不确定你的观点是什么。getClass()只有在你拥有该类的实例时才起作用,是的。我从未说过其他。我的观点是,除非你有一个实例,否则内存中没有任何东西,只有JVM中类的映射(蓝图)。 - jn1kk
@EJP,我觉得我们在争论并且拿走其他人的虚拟网络积分是很愚蠢的,因为问题本身就是模糊不清的。更愚蠢的是,我居然还在试图回答这个问题。 - jn1kk
考虑MyClass.class的结果。不需要存在实例,但它仍然返回一个对象。纠正错误信息并没有什么可笑的地方,我也不知道关于拿走别人的积分的部分是指什么:我在这个帖子上没有投票过任何东西。 - user207421

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