按照惯例,Java中的静态方法只能访问静态字段或其他静态方法。但是,以下简单的代码段似乎违反了约定。让我们考虑Java中的以下简单代码片段。
class Super
{
protected static int x;
protected static int y;
public Super(int x, int y)
{
Super.x=x;
Super.y=y;
}
public static int sum()
{
return(x+y);
}
}
final class Sub extends Super
{
public static int temp=100;
public Sub(int x, int y)
{
super(x, y);
}
public void concreateMethod()
{
System.out.println("\nInstance variable x = "+x);
System.out.println("Instance variable y = "+y);
}
}
final public class Main
{
public static void main(String[] args)
{
Sub s=new Sub(10, 5);
System.out.println("\nAssociating with object x = "+s.x);
System.out.println("Associating with object y = "+s.y);
System.out.println("\nAssociating with class name x = "+Sub.x);
System.out.println("Associating with class name y = "+Sub.y);
System.out.println("\nSummation (Associating with object) = "+s.sum());
System.out.println("Summation (Associating with class name) = "+Sub.sum());
System.out.println("\nAssociating with class name temp = "+Sub.temp);
System.out.println("Associating with object temp = = "+s.temp);
System.out.println("\nConcreate method called.");
s.concreateMethod();
}
}
以上代码使用相应的语句生成以下输出。
与物体x = 10相关联 与对象关联y = 5
与班级名称相关联x = 10
与班级名称关联y = 5
求和(与对象关联)= 15
求和(与班级名称相关)= 15
与班级名称temp = 100相关联 与对象temp = = 100
关联称为Concreate方法。
实例变量x = 10
实例变量y = 5
使用 Sub 类的对象,通过main()方法中的以下语句访问静态字段s和x,尽管它们被声明为 static 超级超级。
Sub s=new Sub(10, 5);
System.out.println("\nAssociating with object x = "+s.x);
System.out.println("Associating with object y = "+s.y);
以下陈述当然是毫无疑问的。
System.out.println("\nAssociating with class name x = "+Sub.x);
System.out.println("Associating with class name y = "+Sub.y);
由于x和y是静态的,因此可以通过这种方式访问它们。
同样是方法调用,请遵守以下陈述。
Sub s=new Sub(10, 5);
System.out.println("\nSummation (Associating with object) = "+s.sum());
System.out.println("Summation (Associating with class name) = "+Sub.sum());
使用超级类的对象以及使用类名 Sub <}来访问静态方法sum()。强>
在 Sub 类中声明静态字段 temp 的类似情况
System.out.println("\nAssociating with class name temp = "+Sub.temp);
System.out.println("Associating with object temp = = "+s.temp);
正在以两种方式访问静态字段 temp 。
为什么会发生这种情况?
答案 0 :(得分:8)
基本上,它是Java IMO设计中的一个缺陷,它允许静态成员(方法和字段)被引用,就像它们是实例成员一样。这在以下代码中可能非常混乱:
Thread newThread = new Thread(runnable);
newThread.start();
newThread.sleep(1000);
看起来就像发送新线程一样,但实际编译成这样的代码:
Thread newThread = new Thread(runnable);
newThread.start();
Thread.sleep(1000);
因为sleep
是一个静态方法,它只会使当前线程休眠。
实际上,甚至没有检查变量是否存在非零性(更多;以前我曾相信):
Thread t = null;
t.sleep(1000);
某些IDE可以配置为对此类代码发出警告或错误 - 您不应该这样做,因为它会损害可读性。 (这是由C#纠正的缺陷之一......)
答案 1 :(得分:5)
那里没有问题。静态方法只能访问静态字段并调用其他静态方法。你的例子中没有任何其他内容。
非静态方法可以访问静态和非静态方法和字段。同样,你的例子都没有违反。
答案 2 :(得分:3)
Sub.temp
和s.temp
是等效的,您可以同时使用它们,它的含义相同。但是第一个更好,因为它表明它是一个静态场。
答案 3 :(得分:2)
Java中的静态方法只能访问静态字段或在同一类中声明的其他静态方法
或者它的超类。
我没有看到任何违规行为,您可以通过其具体对象或类名访问静态字段/方法。两者都指的是同一件事。
答案 4 :(得分:2)
在哪里可以看到静态代码访问的非静态字段或方法?对我来说,一切似乎都很好。
或许令人困惑的是,静态字段和方法可以通过实例以及类名来访问?它肯定是一个很大的丑陋,许多人认为它设计不好,但就是这样。