我正在使用Java;我之前使用过C ++。我正在考虑Java中的静态用法。如果我在类中创建静态方法和变量,为什么我也可以通过对象访问它们?
示例:
class Test{
static int count=0;
int id;
static void updatec(){
count++
}
}
class TestMain
{
public static void main(String args[])
{
Test.count=1;
Test t = new Test();
t.count=5; // Valid WHY ?????
}
}
为什么允许这样做? Java的网站说我们不应该使用obj.static方法/变量 为什么允许这样做?
答案 0 :(得分:7)
静态并不意味着该字段仅适用于该类。它表示类及其所有实例。
在此示例中,类
origin
的类变量Point
在Point.origin中使用类名作为限定符引用,并使用类类型的变量字段访问表达式(§15.11),与p.origin
和q.origin
一样。这两种访问原始类变量的方法访问同一个对象,这可以通过引用相等表达式(§15.21.3)的值来证明:
q.origin==Point.origin
是真的
但是你是对的,从非静态上下文引用静态字段/方法/类通常是个坏主意,它会让开发人员感到困惑。
资源:
答案 1 :(得分:3)
通过实例访问静态字段是合法的,尽管您通常会收到有关它的警告。但是,该字段仍然是静态的,因此每个类只有一个:
Test t = new Test();
Test u = new Test();
t.count = 5;
System.out.println(u.count); // Outputs 5
答案 2 :(得分:2)
没有这是允许的原因。它令人困惑,没有任何意义。好的工具会警告你这个(或者甚至可能让你选择失败的编译)。但它是语言的一部分,因此它永远不会被删除,因为这会破坏现有的代码。
答案 3 :(得分:2)
它确实不应该得到支持。这种支持导致org.apache.commons.cli
命令行解析器中的这个可疑代码。
class OptionBuilder
public static Option create();
public static OptionBuilder withLongOpt(String newLongopt);
public static OptionBuilder withDescription(String newDescription);
这导致了这个:
Option opt =
OptionBuilder
.withLongOpt( "opt" )
.withDescription( "opt description" )
.create( );
如果有一个默认的OptionBuilder
构造函数并且所有静态方法都是实例方法,那将更好,更清晰,更安全。这是StringBuilder
/ StringBuffer
答案 4 :(得分:1)
你不应该意味着你不能。
无论如何,这在C ++中也是允许的。
答案 5 :(得分:1)
您的代码段完全合法,无论是Java还是C ++等。
您似乎对成员的访问限制(私有,受保护,公共)和实例/类别区分(静态关键字)感到困惑。
由于在静态main方法中有一个类Test(名为t)的实例,因此可以使用类Test的实例方法/成员,这符合您引用的文档。
如果计数字段是私有的或受保护的,您将无法访问它,但这与静态无关。
答案 6 :(得分:0)
静态在这种情况下意味着每个类有一个共享实例,而不是每个实例。因此,当您更改t.count时,您将更改整个类和所有实例的“count”成员。
也就是说,这些将打印相同的值:
System.out.println(t.count);
System.out.println(Test.count);
没有什么不合法的,虽然它通常不是一个好主意,因为它看起来像实例数据。