2013-10-08 41 views
1

static方法只能调用同一类的静态方法/字段。问题:静态约束

  1. 为什么非静态方法/域不得提供给static因为一旦static方法被调用,然后JVM创造了一个对象,它可以访问类的其他地方,如果JVM允许?

  2. 为什么static方法允许来自其他类的非静态方法的对象。强加限制他们只能访问其他类的static,并让static访问同一类的非静态成员会导致任何区别?

+0

我希望这一大堆downvotes带有一些很好的建议。 – Rorschach

+0

'一旦静态方法被调用,JVM就为它创建了一个对象'没有JVM不创建对象。 –

+0

除非您有对象,否则您无法访问任何内容。你只是无法访问它。 – Rorschach

回答

2

一次的静态方法被称为比JVM已经创建了一个对象 它

这是不正确的。可以调用静态方法而无需创建定义静态方法的类的对象(记住public static void main())。

为什么静态方法()允许来自其他类的非静态方法的对象。

这是因为可以存在other classe实例不论类定义的静态方法的对象(其访问的other class)是否存在。

结账this link获得进一步的见解。

3

以下是静态方法和字段的java语言规范。希望它能帮到你

8.3.1.1。静态字段

如果一个字段被声明为静态,那么无论该类最终可能创建多少个实例(可能为零),该字段都只有一个字符。一个静态字段,有时称为类变量,在类被初始化时被体现(§12.4)。

未声明为静态的字段(有时称为非静态字段)称为实例变量。只要创建了一个类的新实例(第12.5节),就会为该类或其任何超类中声明的每个实例变量创建与该实例关联的新变量。

8.4.3.2。静态方法

声明为静态的方法称为类方法。

在类方法的标题或正文中使用任何周围声明的类型参数的名称时发生编译时错误。

总是调用一个类方法而不参考特定的对象。尝试使用关键字this(第15.8.3节)或关键字super(第15.11.2节)引用当前对象是编译时错误。

未声明为静态的方法称为实例方法,有时称为非静态方法。

对于一个对象,总是调用一个实例方法,该方法将成为在方法体执行过程中this和super所引用的关键字的当前对象。

+0

我的问题是,为什么这些规则是这样制定的,如果我已经做出了变化,那么它会使Java变得更加美丽。 – Rorschach

+2

我认为黑鸟知道这一点...他问“为什么?” – TheLostMind

+0

那么为什么选择一种特定的风格没有中央资源库。但是你可以通过JSR并从那里获得一些提示。 – Jabir

3

非静态方法有一个隐式this目的是可以在其他非静态方法

静态方法调用不能隐式调用非静态方法,因为它没有对象隐含地使用。没有什么可以阻止你明确地使用对象来调用方法。

例如

class Main { 
    public static void main(String... ignored) { 
     new Main().nonstatic(); // calls non-static method 
    } 

    public void nonstatic() { 
     nonstatic2(); // calls non-static object with implicit reference to "this" 
    } 

    public void nonstatic2() { 
     staticMethod(this); 
    } 

    public static void staticMethod(Main main) { 
     main.nonstatic3(); // static calls non-static with explicit object. 
    } 

    public void nonstatic3() { 
    } 

静态方法只能调用静态方法/来自同一类的字段。

这是不正确的,如示例所示。

为什么非静态方法/域不得提供给静态的,因为一旦静态方法被调用,然后JVM创造了一个对象,

的JVM可以自动地创建一个对象,但这不太可能是有用的,尤其是如果对象没有默认构造函数。

如果JVM允许,可以访问类的其他部分吗?

它可以允许,但不应该恕我直言,因为这会比有用的更混乱。

为什么静态方法允许来自其他类的非静态方法的对象。

静态方法允许来自所有类的对象,而不仅仅是其他类。

强制限制他们只能访问其他类的静态并让静态访问同一类的非静态成员会导致任何区别?

区别在于你没有隐式类的实例这是静态方法的全部要点。

如果您想要一个隐式实例,您可以使用非静态方法。

+0

创建对象与创建其他类的对象并访问它是同义词。它的帮助,但仍然没有清除我的怀疑。 – Rorschach

+0

@Blackbird我已经依次回答了每个问题。我不清楚混淆是从哪里来的。静态与非静态比您想象的要简单得多。 –

1

为什么非静态方法/字段不能用于静态,因为一旦调用了静态方法,JVM就为它创建了一个对象,如果JVM允许,它可以访问其他类的部分?

如果允许静态方法访问非静态方法,这意味着将调用一个实例级方法,而不使用该类的实例。那么你将如何重写该方法?重写将查看调用/调用该方法的对象,以及是否从静态方法直接调用非静态(实例)方法,哪些对象正用于调用?

并从设计的角度来看 -

假设你有一个叫做Dog的类。每只狗都吃,睡觉等。但要记住的最重要的事情是所有这些事情都是特定于Dog实例的。每个对象的状态应该通过实例级别的方法来访问 - 这就是封装的全部要点。如果你说Dog.sleep()。哪只狗应该睡觉?

+0

这听起来很合理,我想根据这个做一个程序,我会再来找你。 – Rorschach

+1

这确实是一个很好的问题...从我+1:P – TheLostMind

2

为了理解为什么static方法不能调用non static方法或访问non static变量,你需要了解对象之间的diffeerence。

Java是一种面向对象的语言。首先定义一个,它包含状态(实例变量)和更改状态(实例变量)的方法。 但是班级不是对象。它只是一个用于创建对象的模板,您可以使用new关键字(创建类的一个实例)。 创建对象后,其变量处于初始状态,然后调用读取或更改对象状态的方法。这些变量和方法是non static,因为它们需要一个类的对象实例。

但是,在一个类中,您可以定义一个不读取或更改状态的方法。方法的行为完全不依赖于实例变量。 这样的方法可以声明为静态的,这意味着不需要该类的实例来运行该方法。

你直接调用一个静态方法上一个类(没有引用的对象):

MyClass.staticMethod();//will not read or change any state, because there is no object here 

你也可以调用的对象上的静态方法,但不会访问对象的状态,因为其行为确实不依赖也不改变对象的状态。呼吁obj.staticMethod();相同MyClass.staticMethod();

//Create an instance of a MyClass 
MyClass obj = new MyClass(); 

//will not read or change any state of obj. 
obj.staticMethod(); 

然而要注意的静态方法并非完全无状态的,他们仍然可以读取或更改静态varibables的状态。

还要注意,在Java中,你不能重写静态方法(不像在Delphi中) - 如果你认为子类需要覆盖静态方法,不要声明方法为静态方法。 因此,如经验法则在特殊用途的工具类中声明静态方法,无论如何不需要实例,例如java.lang.Math,否则 不会将方法声明为静态,即使它没有读取或更改对象的状态,因为您可能需要稍后重写它。