简体   繁体   English

努力理解访问修饰符和关键字“静态”的影响

[英]Struggling to understand the effects of access modifiers and the keyword "static"

I'm pretty new to Java.我对 Java 很陌生。 I've just written a small example to observe the effects of access modifiers.我刚刚写了一个小例子来观察访问修饰符的效果。 Maybe the code does not make much sense since I'm just testing things out.也许代码没有多大意义,因为我只是在测试。

The first code snippet looks like this:第一个代码片段如下所示:

class Tet {
    static double a;
    double b;
    public Tet(double a, double b){
        this.a=a;
        this.b=b;
    }
    
    public void get(){
        a=5;
        
    }
    
    public static void main(String[] args){
        Tet tet1 = new Tet(2, 5);
        Tet tet2 = new Tet(4, 5);
        System.out.println(tet1.a);
        a=4;
        System.out.println(tet1.a);
        tet1.get();
        System.out.println(tet1.a);
        System.out.println(a);
        
    }
}

After this, I made some changes to the code and compiled it again:在此之后,我对代码进行了一些更改并再次编译:

class Tet {
    static double a;
    double b;
    public Tet(double a, double b){
        this.a=a;
        this.b=b;
    }
    
    public static void get(){
        a=5;
        
    }
    
    public static void main(String[] args){
        Tet tet1 = new Tet(2, 5);
        Tet tet2 = new Tet(4, 5);
        System.out.println(a);
        get();
        System.out.println(tet1.a);
        System.out.println(a);
        System.out.println(tet2.a);
        
    }
}

After it runs, the cmd looks like this: enter image description here运行后,cmd 如下所示: enter image description here

I really don't know where is number 4 coming from.我真的不知道4号是从哪里来的。

I can see how these things can be confusing, so no need to apologise.我可以看到这些事情是如何令人困惑的,所以无需道歉。

Firstly, with static members, you shouldn't be using the this keyword as a static member belongs to a class itself and not an instance, ie objects of that class. Firstly, with static members, you shouldn't be using the this keyword as a static member belongs to a class itself and not an instance, ie objects of that class. Or put in a clearer way :或者以更清晰的方式

In the Java programming language, the keyword static means that the particular member belongs to a type itself, rather than to an instance of that type.在 Java 编程语言中,关键字 static 表示特定成员属于类型本身,而不是属于该类型的实例。

This means we'll create only one instance of that static member that is shared across all instances of the class.这意味着我们将只创建 static 成员的一个实例,该成员在 class 的所有实例之间共享。

So change your constructor:所以改变你的构造函数:

public Tet(double a, double b){
    Tet.a =a;
    this.b=b;
}

You can even change the client code.您甚至可以更改客户端代码。

Furthermore, I would also recommend you watch this high-level video on Java memory management: https://youtu.be/4yKxJjYXZ0A or read this article by Oracle . Furthermore, I would also recommend you watch this high-level video on Java memory management: https://youtu.be/4yKxJjYXZ0A or read this article by Oracle .

Access modifiers are more of a general concept in Java and aren't pertinent to a discussion around static members.访问修饰符在 Java 中更像是一个通用概念,与围绕 static 成员的讨论无关。 Basically, it pertains to the visibility of a member, eg classes, variables, etc. Please read this article on the matter.基本上,它与成员的可见性有关,例如类、变量等。请阅读这篇关于此事的文章。

To answer your question, the "number 4" comes from Tet tet2 = new Tet(4, 5);为了回答您的问题,“数字 4”来自Tet tet2 = new Tet(4, 5); because through the constructor, you're still updating the value of the static variable despite not creating a new object of it;因为通过构造函数,尽管没有创建新的 object 变量,但您仍在更新 static 变量的 it'll still have the same memory address , but its value can change as they aren't the same.它仍然具有相同的memory 地址,但它的可以改变,因为它们不一样。 And you change it again to "5" by invoking the get();然后通过调用get(); method.方法。

I hope this clarifies a few things, and let me know if I've made any mistakes in this answer.我希望这能澄清一些事情,如果我在这个答案中犯了任何错误,请告诉我。

There is only one instance of static fields for each class.每个 class 只有一个 static 字段实例。

In this case there is one instance of a .在这种情况下,有a . So when you create the tet2 instance Tet tet2 = new Tet(4, 5);所以当你创建tet2实例时Tet tet2 = new Tet(4, 5); , you just set its value to 4. ,您只需将其值设置为 4。

to understand the meaning of keyword called static please refer to this small tutorial to understand the meaning of static.要理解关键字static的含义请参考这个小教程来理解static的含义。 so when you coded the following 2 lines:因此,当您编写以下 2 行代码时:

    Tet tet1 = new Tet(2, 5);
    Tet tet2 = new Tet(4, 5);

this made 2 instances of the class called Tet but the variable called a is static means it's shared among the 2 instances.这使得 class 的 2 个实例称为Tet ,但称为a的变量是 static 意味着它在 2 个实例之间共享。

so when you write Tet tet1 = new Tet(2, 5);所以当你写Tet tet1 = new Tet(2, 5); it made this diagram as a brief representation:它把这张图作为一个简短的表示:

在此处输入图像描述

but then when wrote Tet tet2 = new Tet(4, 5);但是当写Tet tet2 = new Tet(4, 5); the following diagram happened and a was updated with the new value as it's shared:发生了下图,并且a在共享时使用新值进行了更新:

在此处输入图像描述

so both instances of Tet have that variable called a which is shared meaning if you updated a using any of the 2 instance, it's updated in the second instance also.所以Tet的两个实例都有一个名为a 的变量,如果您使用两个实例中的任何一个更新a ,它也将在第二个实例中更新。

also in C language, making the variable static means that it's only one instance and also private to the file meaning you can't extern that variable to any other file同样在C语言中,使变量static意味着它只是一个实例,并且对文件来说也是私有的,这意味着您不能将该变量外部到任何其他文件

  1. All Java's variables must be known at compile time unlike Python, in either way:与 Python 不同,所有 Java 的变量必须在编译时已知,无论哪种方式:
    1. declare local variable (in this case, declare int a in your main )声明局部变量(在这种情况下,在main中声明int a
    2. qualify variable (in this case, change to Tet.a )限定变量(在这种情况下,更改为Tet.a
    3. ( import variable, but it's a bit longer and redundant this case) import变量,但在这种情况下它有点长且多余)
  2. You're touching static area - an special storage.您正在触摸static区域 - 一个特殊的存储。 static variables are shared across all class instances. static变量在所有 class 实例之间共享 So:所以:
public static void main(String[] args){
    Tet tet1 = new Tet(2, 5); // set Tet's `a` to 2
    // update `a` to 4.
    // `a` is shared across `tet1` and `tet2`!
    Tet tet2 = new Tet(4, 5);
    // Watch out, `Tet`'s `a` is shared! It'll output 4
    System.out.println(tet1.a); 
    System.out.println(tet1.a);
    tet1.get(); // `get`, but updates `a` to 5
    System.out.println(tet1.a); // This will be 5 as well
}

If this answer resolves your question, consider mark this as "resolved":)如果此答案解决了您的问题,请考虑将其标记为“已解决”:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM