2009-05-27 130 views
9

我开始用Java编程。什么是“静态”?

public static void main(String[]args) 

一本书说我应该在这种情况下使用静态,但没有明确说明为什么我应该或它的意思。

你能澄清一下吗?

回答

22

static的概念与某件事是否是类或对象(实例)的一部分有关。

对于main方法声明为static的情况,它表示main方法是一个类方法 - 类是类的一部分,而不是对象的一部分。这意味着另一个类可以通过参考ClassName.method来调用另一个类的类方法。例如,调用的MyClass run方法将通过以下步骤完成:

MyClass.main(new String[]{"parameter1", "parameter2"}); 

在另一方面,如果没有static改性剂的方法或字段意味着它是一个对象的一部分(或也称为“实例”)而不是班级的一部分。

MyClass c1 = new MyClass(); 
c1.getInfo()  // "getInfo" is an instance method of the object "c1" 

由于每个实例可以具有不同的值,的方法的值或字段的:它是由具体的目的是该方法或字段属于,而不是类名的名称称为不同对象中的相同名称不一定必须相同:

MyClass c1 = getAnotherInstance(); 
MyClass c2 = getAnotherInstance(); 

c1.value  // The field "value" for "c1" contains 10. 
c2.value  // The field "value" for "c2" contains 12. 
      // Because "c1" and "c2" are different instances, and 
      // "value" is an instance field, they can contain different 
      // values. 

结合实例和类变量的两个概念。比方说,我们声明包含实例和类变量和方法的新类:

class AnotherClass { 
    private int instanceVariable; 
    private static int classVariable = 42; 

    public int getInstanceVariable() { 
     return instanceVariable; 
    } 

    public static int getClassVariable() { 
     return classVariable; 
    } 

    public AnotherClass(int i) { 
     instanceVariable = i; 
    } 
} 

上面这个类有一个实例变量instanceVariable和类变量classVariable其声明与static修改。同样,有一个实例和类方法来检索值。

实例的构造函数将一个值作为参数分配给实例变量。类变量初始化为42并且从未更改过。

让我们实际使用上面的类,看看会发生什么:

AnotherClass ac1 = new AnotherClass(10); 

ac1.getInstanceVariable();    // Returns "10" 
AnotherClass.getClassVariable();  // Returns "42" 

通知方式的不同类和实例方法被调用。它们以名称AnotherClass引用该类的方式或名称为ac1的实例。让我们进一步去看看这些方法的行为差异:

AnotherClass ac1 = new AnotherClass(10); 
AnotherClass ac2 = new AnotherClass(20); 

ac1.getInstanceVariable();    // Returns "10" 
AnotherClass.getClassVariable();  // Returns "42" 
ac2.getInstanceVariable();    // Returns "20" 
AnotherClass.getClassVariable();  // Returns "42" 

可以看出,实例变量是一个由对象持有(或“实例”),因此,独有的特定情况下,这在这个例子中是ac1ac2所提及的对象。

另一方面,类变量只对整个类都是唯一的。为了获得跨更好这一点,让我们添加一个新的方法将AnotherClass

public int getClassVariableFromInstance() { 
    return classVariable; 
} 

然后,运行以下命令:

AnotherClass ac1 = new AnotherClass(10); 
AnotherClass ac2 = new AnotherClass(20); 

ac1.getInstanceVariable();    // Returns "10" 
ac1.getClassVariableFromInstance(); // Returns "42" 
ac2.getInstanceVariable();    // Returns "20" 
ac2.getClassVariableFromInstance(); // Returns "42" 

虽然getClassVariableFromInstance是一个实例方法,如可以通过为可见通过参考实例ac1ac2来调用,它们都返回相同的值42。这是因为在这两种实例方法中,它们都引用类方法classVariable,该方法对类是唯一的,而不是实例 - 对于类AnotherClass,只有classVariable的单个副本。

我希望一些说明static修饰符用于什么。来自Sun的

The Java Tutorials有一个名为Understanding Instance and Class Members的部分,该部分也涉及两种类型的变量和方法。

+0

很好的解释。 – Zaki 2009-09-06 20:21:49

10

请参阅Wikipedia

例如一个很好的说明,注意如何在数学课,你可以说这样的话

Math.Abs(x); 

不必说

Math m = new Math(); 

这些都是静态方法,因为你不需要一个实例。实例方法是那些要求你有一个类的实例的方法。

Employee e = new Employee(); 
e.Terminate(); 
2

静态方法是适用于整个类,而不是任何特定的成员。 .goExtinct()将成为Duck总体的一种方法,而不是任何特定的鸭子。主要是公共的和静态的,因为必须始终可用,并且它不属于任何特定类别。

0

在任何面向对象的编程语言(如Java或C++)中,您都可以创建在基本级别上类似于建筑物的BluePrints的类。您可以查看蓝图并确定不同组件的连接方式,但您实际上并不在其中。类和对象是一样的。类是蓝图,你创建一个称为对象的类的实例。对于同样的蓝图你可以有多个建筑物,对于一个班级你可以有多个对象。一个对象是一个类的一个实例。类中的每个方法都可以在对象或类的实例上调用,而调用静态方法实际上不需要实例,您可以直接调用ClassName.method(),而无需实际创建类的实例。

1

通常情况下,你必须有一个对象,一个类的实例,以调用它的方法,至少有两个方面的原因:

  1. 这取决于哪一类的对象实现方法被称为。例如,如果您有一个子类的实例,则将调用子类中的方法,即使调用该方法的代码是相同的。
  2. 对象通常具有内部状态(字段),该方法可以引用。如果没有对象实例,这不起作用。

您可以通过调用类的构造函数创建对象实例:

MyObject a = new MyObject(); 

静态方法是没有附加到对象实例的方法。他们可以通过给班级命名来调用。由于这一结果,他们

  1. 不能动态地分派到子类(这就是为什么你得到一个warning when you try to call it on object instances,这只是混乱的语法)
  2. 他们cannot refer to instance state(非静态字段和其他非静态方法) 。

许多人认为静态方法是一个糟糕的设计模式,并建议不要使用它们(除了public static void main)查找单例实例模式的替代方案。

1

在这种特殊情况下,主方法必须是静态的,因为JVM将开始加载类和创建对象。当您启动Java程序时,JVM将查找传递给它的类的定义并加载它。所以Java MyClass将导致加载MyClass类的定义。

按照定义,Java程序将开始在传递给JVM的类的main()方法中作为最初加载的类来执行。此时没有创建MyClass类型的实例(对象),因此主方法必须是静态的,以允许开始执行程序。

如果您想要查看执行Java程序期间正在加载哪些类,您可以使用-verbose:class命令行选项。

0

有时您会想要定义一个独立于该类的任何对象使用的类成员。通常情况下,一个类成员只能与其类的一个对象一起访问。但是,可以创建一个可以自己使用的成员,而不必参考特定的实例。要创建此类成员,请在声明前加上关键字static。当成员声明为静态时,可以在创建其类的任何对象之前访问该成员,而不参考任何对象。你可以声明方法和变量都是静态的。 main()是最常见的静态成员示例。 main()声明为静态 ,因为它必须在任何对象存在之前调用。 这两种类型的静态成员的是静态字段和静态方法:

Static field: 

一个与static关键字声明的字段,例如:

private static int ballCount: 

static关键字的位置是与可更换可见性关键字的位置(私有和公共,以及受保护)。因此,下面的语句工作,太:

static private int ballCount; 

根据约定,大多数程序员往往首先把知名度关键字。

静态字段的值在类的所有实例中都是相同的。换句话说,如果一个类有一个名为CompanyName的静态字段,则从该类创建的所有对象将具有相同的CompanyName值。

当第一次加载类时,会创建并初始化静态字段。当类的静态成员被引用或创建类的实例时,会发生这种情况,以先到者为准。

Static method: 

使用static关键字声明的方法。与静态字段类似,静态方法与类本身相关联,而不与从类创建的任何特定对象关联。因此,在使用类定义的静态方法之前,您不必从类中创建对象。

最着名的静态方法是主要的,它由Java运行时调用以启动应用程序。主要方法必须是静态的,这意味着应用程序默认在静态上下文中运行。

使用静态方法的基本规则之一是,您不能从静态方法访问非静态方法或字段,因为静态方法没有用于引用实例方法的类实例,或者领域。

相关问题