当类不真实时,如何在类中创建变量?

时间:2013-04-20 10:10:10

标签: java oop

我读过一个类是用于创建对象的模型而在物理上不存在而对象是真实的。但是我们在类中创建变量甚至操纵它们。

  1. 当课程不存在时,这怎么可能?

  2. 为这些变量创建的内存是什么时候?

  3. 为这些变量创建的内存在哪里?

4 个答案:

答案 0 :(得分:3)

如果你的意思是静态类变量,那么它们将被保证是初始化的,并且在使用类之前,类中的任何静态初始化代码都会被保证运行。确切地说,未指定的IIRC,以及不同的JVM可以在不同的时间执行。它们与具有这些变量的语言中的全局变量基本相同。

重申一下:静态东西存在并在首次使用之前进行初始化。 JVM实现可以解决这个问题。

但是有一个对象:类对象的实例,它是class Class的子类。


补充:事实上,在Java类中存在如此具体,它们可以被序列化,通过网络传输到不同的JVM,在那里反序列化,在那里创建的类的对象和代码执行。简单的例子是在浏览器中运行的vanilla Java applet。另一个例子是Jenkins / Hudson CI系统中的从属节点,其中从属程序非常小,只包含接收,反序列化和实例化这些类的类和对象的代码,由它们连接的主服务器发送。

答案 1 :(得分:3)

尝试这样思考。这并不能准确解释任何Java运行时是如何做到这一点的,而是一种思考可能对您有帮助的类/对象二元性的方法。

编写类X时,您将描述代码和数据。运行时只需要一些东西的副本 - 例如代码和静态变量 - 以及其他东西的一个副本,例如实例变量。您可以在您编写的类文件中描述这些内容,即使它们将单独存储。

将每个类的一个副本视为一起存储在一块内存中 - 它将被称为C中的结构。在Java中,第一次在程序中引用类X,运行时分配此内存块并将其与类X相关联。

当程序执行诸如“X x1 = new X()”之类的语句时,运行时会分配包含所有实例变量的另一个内存块(或结构),并保留一个指向与x1变量关联的指针的单独指针

现在,当程序执行“Arc arc = x1.getArc();”之类的操作时,运行时使用第一个指针引用方法getArc()中的代码,第二个指针引用相关的实例变量使用x1,并使用这些实例变量执行指定的代码。

OO编程提供了这种将数据与操作它的代码相关联的方式,允许我们将程序组织为组合代码和数据的“对象”。运行时负责为我们跟踪不同的事物副本。

我认为说这个课不存在是不准确的,它只是不会以你编写的形式存在。

答案 2 :(得分:0)

类在运行时在JVM中实际存在。你读到的解释是试图点A,同时留下剩下的细节供以后使用。学校和书籍一直这样做。

在Oracle JVM类中,从加载它们的那一刻开始就有物理表示。事实上,每个对象都有一个指向该类的指针,许多对象可以指向同一个类。

答案 3 :(得分:0)

我不认为某个类或物体是物质的东西,这对我来说似乎有些困惑。类通常被描述为对象的蓝图。必须使用new关键字对对象进行实例化(创建),当实例化对象时,对象的类将用作创建基本默认对象的蓝图。然后,即使在运行时,也可以通过引用存储它的存储器中的位置来操纵对象,并使用对象类中的方法来操作对象类中的字段,至少这是它通常应该完成的方式,所谓的封装,在OOP中非常重要,所以如果你不熟悉封装,我建议你去研究它。

我提到过一个对象可以在运行时进行操作,这是对象和类之间的主要区别。类也可以使用称为反射的东西,但这是另一天的另一个主题。变量或字段有时被描述为地址,它是对存储对象的存储器中的位置的引用。不直接访问对象,它们通过变量引用。

JLabel label;

上面的代码是在内存中放置一个位置,以便在使用JLabel关键字进行实例化时存储new对象。到目前为止还没有创建对象,我们已经声明了一个变量,它是对内存中的位置的引用,我们的对象在创建时将被存储。我们不会直接访问我们的JLabel对象,我们将使用我们创建的'label'变量来引用内存中的实际对象。因此,如果我们创建两个JLabel对象并实例化它们,就像这样......

JLabel label;
label = new JLabel();
JLabel anotherLabel = new JLabel("this is another label");

我们现在有两个JLabel对象。第一个对象首先声明一个引用该对象的变量,然后在一个单独的行上实例化它。第二个对象声明对它的引用,并在一行中实例化它。您可以以任何方式创建对象,并且使用这两种方法有不同的原因。当一个对象被创建时,至少有一个构造函数被调用,第一个对象调用JLabel类中不带参数的构造函数;第二个对象使用JLabel类中的构造函数,该构造函数接受String并创建显示传递给构造函数的文本的对象。

现在假设程序正在运行,我们想要更改第一个对象,因此它将显示一些文本,因为它当前是空白的,因为我们使用了不带任何参数的构造函数。我们可以使用像这样的setText(String)方法来操纵对象。

label.setText("now the first label displays text");

我们没有通过使用该方法以任何方式更改JLabel类,但是我们已经更改了对象,所以它现在显示文本。对于这个答案,我可能会失去一堆声望点,或者不管它们是什么,因为我可能没有完全正确地解释每一个细节但是我回答了这个问题,因为你问的是我很难找到的东西。理解了很长一段时间,可能比大多数人都理解,因为我从未参加过编程课程。有这么多,我不能完全解释这一点,而不是写一本书所以我没有进入范围,访问修饰符,静态等等,但我试图涵盖我认为重要的是要了解你是什么问。就像我说的那样,我没有接受过正规教育,所以请回答一下它的价值,但希望我能够让它更容易理解。

哦,我忘记了你的另一个问题。当创建对象的变量时,将声明存储器中存储对象的位置。此时有一个位置,但内存中的大小仍为0或null,因为没有对象。实例存储对象所需的内存将在实例化对象时填充。