简体   繁体   English

Java中使用此关键字的问题

[英]issues with use of this keyword in java

I am new to java and trying to understand the use of this keyword in java.As per documentation if instance and local variables have same name then local variables mask the instance variables.We use this keyword so that instance variable may not be masked by local variable.Below is the program i was writing to understand the use of this key work but even after use of this keyword instance variable is still getting masked. 我是Java的新手,试图理解java中此关键字的用法。根据文档,如果实例和本地变量具有相同的名称,则本地变量将屏蔽实例变量。我们使用此关键字,以便实例变量可能不会被本地屏蔽下面是我正在编写的程序,用于了解此关键功能的用法,但是即使在使用此关键字实例变量之后,该变量仍然被屏蔽。

class Box{
int height=5;
int length=10;
int breadth=15;


int CalcVol(){
int vol = height*breadth*length;
return vol;
}

Box(int height, int length,int breadth){
this.height = height;
length = length;
breadth = breadth;

System.out.println("height  is "  + height);

}

}

class MyBox{

public static void main(String args[]){
Box mybox1 = new Box(10, 20, 30);
int vol=mybox1.CalcVol();
System.out.println("volume is"  + vol);

}
}

What i am thinking is that variable "height" printed in Box constructor should print 5 ie value of instance variable but its printing 10 ie the value passed as parameter.Please help me on this. 我在想的是,在Box构造函数中打印的变量“高度”应该打印5,即实例变量的值,但打印10,即作为参数传递的值。请对此提供帮助。

You need to add this before every field you want to access : 您需要在要访问的每个字段之前添加this

Box(int height, int length,int breadth){
// ...and move this statement to the beginning, otherwise this.height gets overriden.
System.out.println("height  is "  + this.height);

this.height = height;
this.length = length;
this.breadth = breadth;


}

Otherwise, length = length and breadth = breadth have no effect. 否则, length = lengthbreadth = breadth无效。

It is a name collision problem. 这是一个名称冲突问题。

Within the constructor Box are the parameters height , length , and breadth . 构造函数Box中包含参数heightlengthbreadth Those are also names of three fields within Box . 这些也是Box中三个字段的名称。

In Java, one considers member variables and block variables to be "closer" than field variables. 在Java中,人们认为成员变量和块变量比字段变量“更近”。 As such, if you use the exact same name for both (as you have done), the assignment 这样,如果您对两者使用完全相同的名称(如您所完成的),则分配

 height = height

will assign the parameter height to the exact same value it held (effectively a noop). 会将参数height分配为其完全相同的值(实际上是noop)。

To avoid this issue, you will specify which height you are assigning. 为了避免这个问题,你会指定 height要分配。

 this.height = height;

which is shorthand for "this class's height" or "the field height". 这是“此类的高度”或“场高”的简写。 When there is no name collision, the compiler will assume you meant the field variable; 当没有名称冲突时,编译器将假定您的意思是字段变量。 because there is nothing else with that name in the block. 因为在该区块中没有其他名称。

As an aside, this is a really good reason to learn how to use the final keyword. 顺便说一句,这是学习如何使用final关键字的一个很好的理由。 Final means that the variable can be assigned once, and only once. Final表示变量只能分配一次,并且只能分配一次。 It prevents it from being reassigned in situations you probably would never want. 这样可以防止在您可能永远不会想要的情况下重新分配它。

For example 例如

public Box(final int height, final int width, final int breadth) {

would then throw a compliation error upon 然后会抛出一个错误

  height = height;

because you are reassigning the value of height. 因为您要重新分配高度值。 Such techniques are very valuable when writing code, because they prevent you from writing something you think is a field assignment, when you really wrote a parameter assignment. 此类技术在编写代码时非常有价值,因为当您真正编写参数分配时,它们会阻止您编写您认为是字段分配的内容。

You are performing an assignment here, which will make this.height take on the value of the parameter height . 您将在此处执行分配,这将使this.height接受参数height的值。

this.height = height;

If you want to print the original value of this.height , put the print above the assignment and print with this.height . 如果要打印this.height的原始值,请将打印结果放在赋值上方,并使用this.height打印。

System.out.println("height  was "  + this.height);

More completely, your constructor should look like this. 更完整地说,您的构造函数应如下所示。 Note that you need to prefix with the this keyword on every access to any instance variable that is shadowed by a local variable. 请注意,每次访问由局部变量隐藏的任何实例变量时,都需要在this关键字前面添加前缀。

Box(int height, int length,int breadth){
    System.out.println("height  was "  + this.height);
    this.height = height;
    this.length = length;
    this.breadth = breadth;
}

For your class: 对于您的班级:

class Box{
    int height=5;
    int length=10;
    int breadth=15;

    Box(int height, int length,int breadth){
        this.height = height;
        length = length;
        breadth = breadth;

        System.out.println("height  is "  + height);

    }

 }

When you construct Box, the following is happening: 当您构造Box时,会发生以下情况:

  1. Instance variable height is being set to the constructor parameter height 实例变量的height被设置为构造函数的参数height
  2. Constructor parameter length is being set to itself (not changing instance variable length ) 正在将构造方法参数length设置为其自身(不更改实例变量length
  3. Constructor parameter breadth is being set to itself (not changing instance variable breadth ). 构造函数参数的breadth被设置为自身(不改变实例变量的breadth )。

What you probably want to do in the constructor is set your instance variables with the values passed into the constructor like this: 您可能要在构造函数中执行的操作是使用传递到构造函数的值来设置实例变量,如下所示:

Box(int height, int length,int breadth){
    this.height = height;
    this.length = length;
    this.breadth = breadth;
}

Rather than not understanding the usage of the this keyboard in Java, I think OP isn't understanding object oriented programming in general, seeing how he's trying to print out "5" when the value has already changed. 我认为OP并没有理解一般的面向对象程序设计,而是不了解Java中this键盘的用法,而是了解他如何在值已更改时打印“ 5”。 The this keyword becomes a lot less confusing once you understand that concept. 一旦您理解了这个概念, this关键字就会变得不那么混乱。

Suppose you have your class Box, and it only has one value, height: 假设您有Box类,并且它只有一个值height:

class Box {
    // This is a instance variable, that is, each new instance of Box 
    // has a different height variable even if they are all equal to 5
    // initially. It's a different variable in memory.
    int height = 5; 

    // Here's our constructor that sets this instance's value of height
    Box(int height){
        this.height = height;
    }

When you make a new Box, you are making a new Box Object - for each object the height will initially start at 5, but you are changing the height of that instance of Box in your constructor. 当创建一个新Box时,您正在创建一个新Box对象 -每个对象的高度最初将从5开始,但是您正在更改构造函数中Box实例的高度。

Box box1 = new Box(10); // Height was originally 5, but changed to 10 in the constructor
Box box2 = new Box(20); // Height was originally 5, but changed to 20 in the constructor
Box box3 = new Box(30); // Height was originally 5, but changed to 30 in the constructor

When you get to the following line of code in your original program: 当您在原始程序中到达以下代码行时:

System.out.println("height  is "  + height);

It doesn't matter if it was this.height or height , it will never return 5. You already changed the value of the instance's height in the constructor . 不管是this.height还是height ,它永远不会返回5。 您已经在构造函数中更改了实例的height值

So then. 那就这样 How do we print out a default height of 5? 我们如何打印默认高度5? You can't. 你不能 Not with the same variable name. 不能使用相同的变量名。 You have to define constants in the class (like final int HEIGHT = 5 ) which represent the default values for that class, or use another constructor that doesn't set those values. 您必须在类中定义常量(例如final int HEIGHT = 5 ),以代表该类的默认值,或者使用另一个未设置这些值的构造函数。

class Box{

    int height=5;
    int length=10;
    int breadth=15;

    int CalcVol(){
        int vol = height*breadth*length;
        return vol;
    }

    Box() {
        System.out.println("height  is "  + height);
    }

    Box(int height, int length,int breadth) {
        this.height = height;
        this.length = length;
        this.breadth = breadth;
        System.out.println("height  is "  + height);
    }
}

class MyBox{

    public static void main(String args[]){

        Box mybox1 = new Box(10, 20, 30); // this will never print 5, and always 10
        Box mybox2 = new Box(); // this will always print 5

    }
}

However, if you move the print statement above the assignment and used this.height , like Maxim Bernard did, then it will print out 5, since we didn't change the value yet. 但是,如果将print语句移到赋值上方并像Maxim Maxim Bernard一样使用this.height ,它将打印出5,因为我们尚未更改该值。

    Box(int height, int length,int breadth) {
        System.out.println("height  is "  + this.height); // this will print out 5
        this.height = height;
        this.length = length;
        this.breadth = breadth;
    }

If this is really confusing, rather than trying to understand Java's this keyword I suggest just reading a few articles on OOP. 如果这确实令人困惑,则建议不要阅读Java的this关键字,而建议阅读一些有关OOP的文章。 You'll understand then that this simply means the current instance of a class . 然后您将了解, this仅表示类的当前实例

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

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