在java中创建的所有对象都是main方法中的静态对象吗?

时间:2014-08-16 14:19:32

标签: java object memory memory-management static

要访问类的非静态成员/变量,您需要先在public static void main(String args[])方法中创建一个对象。

这是否意味着创建的所有对象都是static

我需要一个明确的解释,而且我需要知道如何为类的static方法/变量完成内存分配

我知道这听起来像个天真的问题,但我需要了解它。

2 个答案:

答案 0 :(得分:1)

不,他们不是。如果这是真的,那么就不会存在任何非静态的东西,因为所有(普通的)Java程序都以main(String[])方法开头。

对象永远不会是静态的。

你可以创建一个类,比如对象的蓝图

public class Aa {

    public void doSomething() { ... }

    public static void doMore() { ... }

}

您可以像这样创建该类的实例(即对象):

new Aa();

如果您运行类,则会启动Java虚拟机并搜索main(String[])方法。由于还没有任何对象实例,因此必须将该方法声明为static

public class Main {

    public static void main(String[] args) {

        // Without an instance of Aa, you can only call static methods OF
        // THAT CLASS:
        Aa.doMore();

        // This will throw a compiler error:
        // non-static method doSomething() cannot be referenced from a
        // static context, because the method is not declared static.
        Aa.doSomething();

        Aa instanceOfAa = new Aa(); // Create a new object of type Aa.

        // Since we've created an instance of the class Aa (thus it is an
        // object), we can call non-static methods OF THAT CLASS if we call
        // the reference to it. The variable myInstanceOfAa refers to an
        // instance of class Aa, thus we can call non-static methods on it,
        // like this:
        instanceOfAa.doSomething();
    }
}

请参阅The Java Tutorials

  

有时,您希望拥有所有对象共有的变量。这是通过静态修改器完成的。在声明中具有static修饰符的字段称为静态字段或类变量。它们与类相关联,而不是与任何对象相关联。该类的每个实例共享一个类变量,该变量位于内存中的一个固定位置。任何对象都可以更改类变量的值,但也可以在不创建类实例的情况下操作类变量。

所以你不需要一个类的实例(即一个对象)来获取它。

我建议你阅读Java Tutorials

内存

您的问题的记忆部分可能已被回答here

答案 1 :(得分:1)

你说明了这一点:

  

要访问类的非静态成员/变量,您需要先在public static void main(String args[])方法中创建一个对象。

这只是部分正确的。是。您执行需要创建类的实例才能使用其非静态成员。但是不需要在main方法中创建实例。实际上,您不一定需要在main中创建任何对象。 (还有其他方法可以创建应用程序的“原始”对象......实际上,您的应用程序可能甚至没有main。)

  

这是否意味着创建的所有对象都是静态的?

没有。出于多种原因。

  • 你的初步前提并非(完全)真实。
  • 某些(原始)对象是由static方法创建的,这并不意味着所有对象都是以这种方式创建的。
  • 最重要的原因是在Java中没有静态对象这样的东西!

static的概念 1 适用于字段和方法。静态字段或方法是不是单个对象(实例)的成员的字段或方法。但这并不适用于对象(实例)本身。在Java中,对象始终是独立的实体,并且它们永远不是其他成员...至少在编程语言级别。

例如:

public class Example {

    public static String test;

    public static void main(String[] args) {
        test = new String("Hi mum!");
    }
}

test变量为static,我们分配对新创建的String对象的引用。但是稍后,我们可以将test的值分配给非静态变量,或者将对不同对象的引用分配给test。我们创建的对象与我们可能在非静态上下文中创建的对象没有什么不同。

  

我需要知道如何为类的静态方法/变量完成内存分配。

  • 如果调用new的方法是静态的或非静态的,对象的内存分配完全相同
  • 如果您要分配引用的字段是静态或非静态的,则

就内存管理而言,静态和非静态字段有几点不同:

  • 静态字段是垃圾收集根。这意味着它们指向的对象始终 2 可达;即他们不会被垃圾收集。

  • 静态字段本身属于到通常为堆节点的帧。 (对于较旧的JVM,它们位于permgen堆中,但是使用Java 8时,普通堆和permgen堆之间的区别已经消失。)当加载类时,JVM会分配此帧并将其挂钩到其私有类数据结构中。


1 - static关键字也用于嵌套类声明,但它意味着一些不同的东西。我只提到这个“完整性”。

2 - 如果应用程序或框架实现“热加载”,并且您没有“类加载器泄漏”,则可以对类及其关联的静态进行垃圾回收。因此,static字段并非始终可永久访问。