【问题标题】:how to operate static?如何操作静态?
【发布时间】:2013-06-07 04:32:01
【问题描述】:

每当我们使用静态时,我们不需要创建一个类的引用变量。我们可以通过<class_name>直接访问类

但是当我们编写如下代码时:

class Abc
{
    static void show()
    {
        System.out.println("Hey I am static");
    }
}

class Test
{
    public static void main(String args[])
    {
        Abc.show();            //1
        new Abc().show();      //2
    }
}

第 1 行和第 2 行如何工作。

的意义是什么
new Abc().show();

【问题讨论】:

  • 请缩进您的代码。 ;)
  • 静态方法与相关联,而不是实例。调用该方法的“正确”方式是使用类名(即 Abc.show())调用它。显示这一点的最明显原因是,如果您正在浏览代码并看到实例调用方法,您将假定该方法将与实例相关联,而不是与类相关联。让实例调用静态方法可能会误导/混淆查看您的代码的人。
  • 在实例上调用静态方法会导致警告,尽管它也只会调用类上的静态方法。它编译的第三个原因仅仅是因为无论如何都给出了类和实例,但这是一种糟糕且毫无意义的做法。
  • 如果我的回答中肯,请考虑投赞成票。谢谢。

标签: java default operator-keyword static-members


【解决方案1】:

因为你的 ABC 类没有覆盖默认构造函数。

相当于:

class Abc{
    public Abc(){super();}

    static void show(){
         System.out.println("Hey I am static");
    }
}

因此,通过执行new Abc().show();,您只是在创建类的新 Abc 对象并通过该对象调用 ABC 类的静态方法(它会显示警告,因为这不是调用静态方法的正确方法).`

【讨论】:

    【解决方案2】:

    使用实例(尽管它有效)是调用static 方法(或访问静态字段)的错误方式因为静态表示它的类的成员/type 而不是实例。

    因此,编译器会将实例替换为 Class 类型(由于静态绑定)。换句话说,在运行时ABC.show() 被执行而不是new ABC().show()

    但是,您的源代码仍然看起来令人困惑。因此,这被认为是一种不好的做法,甚至会导致来自 Eclipse 等 IDE 的警告。

    【讨论】:

      【解决方案3】:

      您可以使用实例中的静态方法,例如 new Abc().show(),但它可能会造成混淆,因此不推荐使用。

      静态方法使用className.staticMethod(),否则使用classInstance.instanceMethod()

      【讨论】:

        【解决方案4】:

        这简单意味着您正在为 ABC 创建对象,而不是尝试通过对象访问此变量。

        但是,在编译时,

        new Abc().show(); 
        

        转换为Abc.show().

        【讨论】:

        • 你有这方面的参考吗?
        • 我使用带有 -c 选项的 javap 命令。这是命令 public static void main(java.lang.String[]); 的输出。代码:0:invokestatic #2 // Method Hi.sayHi:()V 3: new #3 // class Hi 6: dup 7: invokespecial #4 // Method Hi."":()V 10: astore_1 11: aload_1 12: pop 13: invokestatic #2 // Method Hi.sayHi:()V 16: return public static void main(String a[]){ Hi.sayHi();嗨嗨=新嗨();嗨.sayHi(); }
        • 我怀疑编译器会把它去掉。构造函数中可能有代码(我知道,不好的做法),甚至是静态代码......
        【解决方案5】:

        Static 关键字建议每个类只有一个副本,现在您已经创建了静态方法,并且您正在使用 Classname.methodname() 进行访问,这是适当的方式,因为当类加载到 JVM 时,它的实例将被创建,因此无需显式创建新的类的对象。希望有意义。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-01-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多