访问静态变量和方法时C#和Java的区别

Ank*_*hah 2 c# java static-members

在Java中,静态方法和变量可以通过对象引用访问,就像在下面的程序中一样,它工作得很好:

//StaticDemo.java
class StaticVerifier{
    private int a,b;
    public StaticVerifier(int a,int b){
        this.a = a;
        this.b = b; 
        System.out.println("Values are "+this.a+" "+this.b);
    }   
    public static void takeAway(){
        System.out.println("This is a static method...");
    }
}
public class StaticDemo{
    public static void main(String[] args){
        StaticVerifier sv = new StaticVerifier(3,4);
        sv.takeAway();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试在C#中转换相同的代码时,它不允许对象访问静态方法并给出编译时错误.请参阅下面的代码和相关错误:

//StaticDemo.cs
using System;
public class StaticVerifier{
    private int a,b;
    public StaticVerifier(int a,int b){
        this.a = a;
        this.b = b; 
        Console.WriteLine("Values are "+this.a+" "+this.b);
    }   
    public static void takeAway(){
        Console.WriteLine("This is a static method...");
    }
}
public class StaticDemo{
    public static void Main(string[] args){
        StaticVerifier sv = new StaticVerifier(3,4);
        sv.takeAway();                  // here, unable to access static methods, but can use classname rather than objectname !
    }
}
Run Code Online (Sandbox Code Playgroud)
Errors:
 StaticDemo.cs(17,3): error CS0176: Member 'StaticVerifier.takeAway()' cannot be
        accessed with an instance reference; qualify it with a type name instead
StaticDemo.cs(10,21): (Location of symbol related to previous error)
Run Code Online (Sandbox Code Playgroud)

任何人都可以告诉我为什么C#没有这种可访问性和Java,虽然两者都基于面向对象的范式?(我主要是指"为什么供应商已经这样做了?")

T.J*_*der 7

通过实例引用访问静态成员是Java的一个怪癖,与面向对象无关.

正确的方法(在C#和Java中)都是takeAway通过类引用访问的StaticVerifier.takeAway().Java 允许你使用实例引用,但同样,这是一个怪癖,我相信只有Java才有这个怪癖.

Java的这个怪癖可能会让人非常困惑.例如:

public class Example {

    public static final void main(String[] args) {
        Example e = null;
        e.staticMethod();
    }

    static void staticMethod() {
        System.out.println("staticMethod");
    }
}
Run Code Online (Sandbox Code Playgroud)

有人可能会认为失败了NullPointerException.但它没有,因为staticMethod是静态的,所以你并不需要一个实例来调用它,这样其实enull无关紧要.

通过实例引用访问静态也会导致生成不必要的字节码.e.staticMethod();结果是:

2: aload_1       
3: pop           
4: invokestatic  #2                  // Method staticMethod:()V

例如,e加载然后弹出内容.但Example.staticMethod();只是生成

2: invokestatic  #2                  // Method staticMethod:()V

并不是真的很重要,JVM中的优化器可能会解决它,但......