java中局部变量和类变量的行为

java中局部变量和类变量的行为,java,static,class-level,Java,Static,Class Level,我是Java编程语言的新手 我对C和C++很熟悉,但是不能理解下面的程序的行为。 公共类测试{ 静态int x=11; 私人智力y=33; 公共无效方法1(整数x){ 测试t=新测试(); 这个.x=22; y=44; System.out.println(“Test.x:+Test.x”); System.out.println(“t.x:+t.x”); System.out.println(“t.y:+t.y”); System.out.println(“y:+y”); } 公共静态

我是Java编程语言的新手
我对C和C++很熟悉,但是不能理解下面的程序的行为。
公共类测试{
静态int x=11;
私人智力y=33;
公共无效方法1(整数x){
测试t=新测试();
这个.x=22;
y=44;
System.out.println(“Test.x:+Test.x”);
System.out.println(“t.x:+t.x”);
System.out.println(“t.y:+t.y”);
System.out.println(“y:+y”);
}    
公共静态void main(字符串参数[]){
测试t=新测试();
t、 方法1(5);
}
}
正确输出:

Test.x: 22
t.x: 22
t.y: 33
y: 44
预期产出:

Test.x: 22
t.x: 22
t.y: 44   // As variable y is modified inside the function.
y: 44

甚至从
y=44更改行到<代码>此。y=44未给出预期的输出

问题在于,您不是指实际创建的对象。您正在从具有新变量的其他实例中引用变量

        Test t = new Test();
        this.x = 22;
        y = 44;

        System.out.println("Test.x: " + Test.x);
        System.out.println("t.x: " + t.x);
        System.out.println("t.y: " + t.y);
        System.out.println("y: " + y);
如果仔细看第一行
Test t=new Test()

您没有在y分配给44的特定实例上调用method1。因此,您可以看到顶级值

如果重命名实例,则会更加清楚。而不是
t
始终


这就是混乱的原因,而且,您在内部调用
method1()
,这可能会导致无休止的循环

method1
中,您有两个对象
t
this
(当前对象)和行

y = 44; // equivalent to this.y = 44
正在设置当前对象的值,因此

this.y == 44; or y == 44;
t.y == 33;

您应该理解的一点是,y=44或this.y=44不会修改t.y,如果要修改t.y的值,可以执行以下操作:
t、 y=44

静态变量和非静态变量之间的基本区别

class Student {
    private int id;
    private String name;
    static String collegeName;
}
class Student {
    private int id;
    private String name;
    static String collegeName;
    public static void main(String[] args) {
        String s1 = Student.collgeName;
        String s2 = collgeName;
        Student student = new Student();
        String s3 = student.name;
        int id = student.id;
    }
}
对于Students的每个对象
非静态
属性id和name将与其初始值(0&null)一起加载到内存中,每个对象的id和name可以不同。但collegeName只会被加载一次,此时类被加载以执行。因此,对于
的每个对象,学生将拥有相同的学院名称。这就是所谓的
静态

访问静态和非静态变量

class Student {
    private int id;
    private String name;
    static String collegeName;
}
class Student {
    private int id;
    private String name;
    static String collegeName;
    public static void main(String[] args) {
        String s1 = Student.collgeName;
        String s2 = collgeName;
        Student student = new Student();
        String s3 = student.name;
        int id = student.id;
    }
}
可以使用静态变量的名称或使用类名直接访问静态变量。当存在静态全局变量和局部变量时,静态变量应与类名一起使用

public static void main(String[] args) {
    String s1 = Student.collgeName;
    String collgeName = "foo";
    String output = collgeName;
}
这里的
输出将具有值“foo”。局部变量总是比全局静态变量具有更高的优先级,这就是为什么
String output=s1将输出值设置为
null

在静态块内,必须借助参考变量访问非静态的变量(我们必须创建一个对象)。Main方法是静态的,这就是为什么我们必须创建
Student
的对象来访问
id
name
的值,否则会产生编译时错误

关于非静态块的盲规则

class Student {
    private int id;
    private String name;
    static String collegeName;
}
class Student {
    private int id;
    private String name;
    static String collegeName;
    public static void main(String[] args) {
        String s1 = Student.collgeName;
        String s2 = collgeName;
        Student student = new Student();
        String s3 = student.name;
        int id = student.id;
    }
}
每个非静态块将使用一个默认的
this
关键字,该关键字表示在使用类级别(静态和非静态)变量时调用块的当前引用。示例java代码

class Student {
     private int id;
     private String name;
     static String collegeName;
     void setData() {
         id = 1;
         name = "foo";
         collegeName = "FooCollege";
     }
     public static void main(String[] args) {
         Student student = new Student();
         student.setData();
     }
}
这就是编译相同的代码以获取类文件时发生的情况

class Student {
     private int id;
     private String name;
     static String collegeName;
     void setData() {
         this.id = 1;
         this.name = "foo";
         this.collegeName = "FooCollege"; // which will be again as Student.collegeName
     }
     public static void main(String[] args) {
         Student student = new Student();
         student.setData();
     }
}
此处
this
表示来自main方法的参考变量
student
表示调用块的参考变量。

说到问题,main方法创建一个
Test
对象,并在其引用上调用
method1()。因此,在
method1
内部,这只不过是在main方法中创建的参考变量
t
,而
t
是该方法的局部参考变量。现在让我们以类文件格式重新编写代码

public void method1(int x) {
   Test t = new Test();
   this.x = 22;  //  or Test.x = 22;
   y = 44;  //  or this.y = 44;
   /* 
       Test object inside method1 and main method are in two different locations.
       When we write this.y = 44; the y inside the main method object will be changed and not the one created inside method1.
   */
   System.out.println("Test.x: " + Test.x);
   System.out.println("t.x: " + t.x);
   System.out.println("t.y: " + t.y); // means the y inside the object created inside method1
   System.out.println("y: " + y); // means the y inside the object created inside main method
}

y
不是静态字段。这是一个实例字段。所以每个测试实例都有自己的y。该方法修改
y
(即
this.y
),而不是
t.y
。如果你把车漆成黑色,你爸爸的车就不会变黑。这里也一样。这也给了C++中同样的结果,你说你很熟悉。为什么你会对Java的行为方式感到惊讶?我想这可能是Java中一些变量作用域的问题,我无法理解。但是在知道这个行为背后的实际原因之后,同样的情况也将出现在C++中。