简体   繁体   English

Java中的堆栈变量(新手)

[英]Stack variables in Java (newbie)

I am staring to study java and currently I am learning about the classes setters. 我正盯着Java学习,目前正在学习有关类的设置方法。 I see that the most common way to make a setter is something like this. 我看到最常见的制作传承人的方式是这样的。

class Apple{
    private String _name;

    //Setters
    public void setName(String name){
        _name = name;
    }
}

I am used to C so this code raises me a question. 我习惯了C,所以这段代码提出了一个问题。 If I am setting _name = name in a function, after this function is completed and his stack is discarded why does the variable _name still stores the right value? 如果我在函数中设置_name = name,那么在完成该函数并将其堆栈丢弃后,为什么变量_name仍存储正确的值? This is confusing because in C if I assig a pointer to another pointer inside a function like this it would probably cause a segmentation fault (since name is a temporary variable). 这是令人困惑的,因为在C中,如果我将一个指针指向这样的函数内的另一个指针,则可能会导致分段错误(因为名称是临时变量)。

In Java, you as an user don't have control over the stack as in C/C++ languages. 在Java中,您作为用户无法像C / C ++语言那样对堆栈进行控制。

In addition, all non-primitive data types (int, double, etc.) are stored in the heap. 此外,所有非原始数据类型(int,double等)都存储在堆中。 The user is only able to use references or pointers and is not required to perform any kind of memory management, since a mechanism known as garbage collector already frees those instances which haven't any reference to them. 用户只能使用引用或指针,并且不需要执行任何类型的内存管理,因为称为垃圾收集器的机制已经释放了没有任何引用的实例。 Therefore, there are no such thing as pointers in Java, although you can assign a null value to a non-primitive variable: Foo f = null; 因此,在Java中没有指针之类的东西,尽管您可以为非基本变量分配一个null值: Foo f = null;

Therefore, in Java you could literally behave what this C++ code does: 因此,在Java中,您可以从字面上表现此C ++代码的作用:

class Foo {
    Foo( int a ) {}
};

void bar( int a ) {
   Foo f(a); // f is placed in the stack
}

The only way you can create an instance of Foo in java would be like this: 在Java中创建Foo实例的唯一方法是这样的:

void bar( int a ) {
   Foo f = new Foo(a); /* f is a reference to the new instance
                        * (placed in heap) */
}

Actually, name is an instance variable and setName() is an instance method. 实际上, name是实例变量,而setName()是实例方法。 This means that there is a separate copy of name for every object of the class Apple . 这意味着Apple类的每个对象都有单独的name副本。 The setName() method sets the value for the global variable of the object it is called with to that of its argument. setName()方法将调用对象的全局变量的值设置为其参数的值。 So, even after the stack of the method is discarded, the object exists and so does the value of this object's copy of name . 因此,即使在丢弃方法堆栈之后,该对象仍然存在,并且该对象的name副本的值也是如此。 See this example below: 请参见下面的示例:

class Apple {
    private String name; //instance variable

    public void setName(String name) {
        this.name = name; //same as what you have written
    }

    //main method
    public static void main(String[] args) {
        Apple obj = new Apple(); //object created
        Apple obj2=new Apple();
        obj.setName("Yolo");
        obj2.setName("Yay!");
        System.out.println(obj.name); //displays obj's copy of name that holds the value "Yolo"
        System.out.println(obj2.name); //displays obj2's name
    }
}

This displays 显示

Yolo
Yay!

I hope this makes it clear to you. 我希望这可以使您清楚。

You are setting the reference of name to the reference of _name so they look in the same spot in memory. 您要将name的引用设置为_name的引用,以便它们在内存中的同一位置出现。 Therefore when the instance of setName disappears and the variable name with it the reference stored in _name remains. 因此,当setName实例消失并且变量名称带有它时,_name中存储的引用仍然保留。

Since you set _name to private it can only be accessed inside the class Apple. 由于您将_name设置为private,因此只能在Apple类中进行访问。 You cant change it within your main method and that's why you create the set method so it can be changed by outside classes (Ie Your main method) 您不能在main方法内更改它,这就是为什么要创建set方法以便可以由外部类更改的原因(即您的main方法)

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

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