当先锋百科网

首页 1 2 3 4 5 6 7

1. this关键字

this关键字主要有以下三个方面的用途:

  • this调用本类属性
  • this调用本类方法
  • this表示当前对象

1.1 this调用本类属性

先看一段代码:

class Person{
    private String name;
    private int age;

    public Person(String name, int age)
    {
        name = name;
        age = age;
    }
    public String getPersonInfo()
    {
        return "姓名:" + name + " 年龄:" + age;
    }
}

public class Test{
    public static void main(String[] args){
        Person per = new Person("张三", 20);
        System.out.println(per.getPersonInfo());
    }
}

运行结果如下:
在这里插入图片描述
大家会发现,明明实例化对象时,Person(“张三”, 20); 但是得出的结果却是不是我们想要的结果。我们再看构造方法有了下面的代码:

        name = name;
        age = age;

通过以上代码我们可以发现,当参数中属性同名是,类中属性无法被正确赋值。此时我们加上this关键字便可正确给对象属性赋值。

        this.name = name;
        this.age = age;

只要在类中方法访问类中属性,一定要加上this关键字。

1.2 this调用本类方法

this调用本类方法有一下两种情况:

  1. 调用普通方法
  1. 调用构造方法

1.2.1 this调用普通方法

举例:

class Person{
    private String name;
    private int age;

    public Person(String name, int age)
    {
        this.name = name;
        this.age = age;
        this.print();//调用普通方法
    }
    public String getPersonInfo()
    {
        return "姓名:" + name + "  年龄:" + age;
    }
    public void print()
    {
        System.out.println("*******************");
    }
}

public class Test{
    public static void main(String[] args){
        Person per = new Person("张三", 20);
        System.out.println(per.getPersonInfo());
    }
}

运行结果如下:
在这里插入图片描述
虽然调用本类普通方法不需要加上this也可以正常调用。但强烈建议加上,加上this的目的可以区分方法定义的来源(在继承中有用)

1.2.2 this调用构造方法

举例:先观察构造方法中存在的问题

class Person{
    private String name;
    private int age;

    public Person()
    {
        System.out.println("********产生一个新的Person对象*******");
    }
    public Person(String name)
    {
        System.out.println("********产生一个新的Person对象*******");
        this.name = name;
    }
    public Person(String name, int age)
    {
        System.out.println("********产生一个新的Person对象*******");
        this.name = name;
        this.age = age;
    }
    public String getPersonInfo()
    {
        return "姓名:" + name + "  年龄:" + age;
    }
}

public class Test{
    public static void main(String[] args){
        Person per1 = new Person();
        Person per2 = new Person("李四");
        Person per3 = new Person("张三", 20);
        System.out.println(per1.getPersonInfo());
        System.out.println(per2.getPersonInfo());
        System.out.println(per3.getPersonInfo());
    }
}

在这里插入图片描述
上述代码在构造方法中出现了一些代码重复问题,想要解决此类问题,就需要用到this.
在Java中,支持构造方法的互相调用(this)。
修改代码如下:

class Person{
    private String name;
    private int age;

    public Person()
    {
        System.out.println("********产生一个新的Person对象*******");
    }
    public Person(String name)
    {
        this();//调用本类无参构造
        this.name = name;
    }

    public Person(String name, int age)
    {
        this();//调用本类有一个参数的构造方法
        this.age = age;
    }
    public String getPersonInfo()
    {
        return "姓名:" + name + "  年龄:" + age;
    }
}

public class Test{
    public static void main(String[] args){
        Person per1 = new Person();
        Person per2 = new Person("李四");
        Person per3 = new Person("张三", 20);
        System.out.println(per1.getPersonInfo());
        System.out.println(per2.getPersonInfo());
        System.out.println(per3.getPersonInfo());
    }
}

运行结果如下:
在这里插入图片描述
使用this调用构造方法时请注意:

  1. 只能在构造方法中使用this调用其他的构造方法,不能再成员方法中使用。
  2. 在构造方法中,使用this调用构造方法的语句必须位于第一行,且只能出现一次。下面的写法时非法的,必须在写代码时注意。
Public Person(String name, int age) {
	this.age = age;
	this(name);	//调用有参的构造方法。由于不在第一行,编译错误。
}

运行结果如下:
在这里插入图片描述

  1. 不能在一个类的两个构造方法中使用this互相调用,下面的写法编译会报错。
    public Person(){
        this("lisi");//调用有参的构造方法
        System.out.println("****无参构造****");
    }
    public Person(String name){
        this(); //调用无参的构造方法
        System.out.println("****有参构造****");s
    }

运行结果如下:
在这里插入图片描述

1.3 this表示当前对象

举例:this表示当前对象

class Person{
    public void print(){
        System.out.println("[PRINT]方法:" + this);      
    }
}

public class Test{
    public static void main(String[] args){
        Person per1 = new Person();
        System.out.println("[MAIN]方法: " + per1);
        per1.print();
        System.out.println("************************");
        Person per2 = new Person();
        System.out.println("[MAIN]方法: " + per2);
        per2.print();
    }
}

在这里插入图片描述
只要调用了本类中的方法,这个this就表示当前执行的对象。

2. static关键字

在Java类中定义了一个static关键字,它用于修饰类的成员,如成员变量、成员方法以及代码块等。

2.1 static属性(类属性)

  在定义一个类时,只是在描述某类事物的特征和行为并没有产生具体的数据。只有通过new关键字创建该类的实例对象后,系统才会为每个对象分配内存空间,存储各自的数据。
  但是有时候需要某些特定的数据在内存中只有一份,而且能够被一个类的所有实例对象所共享。
举例:实例属性的内存分析

class Person{
    String country = "中国";
    String name;
    int age;

    public void getPersonInfo(){
        System.out.println("姓名:" + this.name + ",年龄:" + this.age + ",国家:" + this.country);
    }
}

public class Test{
    public static void main(String[] args){
        Person per1 = new Person();
        per1.name = "zhangsan";
        per1.age = 10;
        Person per2 = new Person();
        per2.name = "lisi";
        per2.age = 20;

        per1.getPersonInfo();
        per2.getPersonInfo();

    }
}

运行结果如下:
在这里插入图片描述
内存分析图如下:
在这里插入图片描述
传统属性所具备的特征:保存在堆内存中,且每个对象独享属性。
描述共享属性,只需在属性前添加static关键字即可。
static属性又称为类属性,保存在全局数据区的内存之中,所有对象都可以进行该数据区的访问。
修改上述代码:

此时的内存分析图如下所示:
在这里插入图片描述
结论:

  1. 访问static属性应使用 类名称 . 属性名
  2. 所有的非static属性(实例变量)必须在对象实例化后使用,而static属性不收对象实例化控制
  3. 修改static属性,所有对象都同步此属性。应使用一下方法修改:

定义类时,如何选择实例变量和类属性呢?

  1. 在定义类时,99%的情况都不会考虑static属性,以非static属性(即实例变量)为主
  2. 如果需要描述共享属性的概念,或者不受对象实例化控制,使用static

注意:
  static关键字只能用于修饰成员变量,不能用于修饰局部变量,否则编译会报错,下面代码时非法的:

2.2 static方法(类方法)

使用static定义的方法,直接通过类名进行访问。
  类名称 . 方法名
举例:观察static方法

class Person{
    private static String country;
    private String name;
    private int age;

    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }

    public static void setCountry(String s){
        country = s;
    }

    public void getPersonInfo(){
        System.out.println("姓名:"+this.name+",年龄:"+this.age+"国家:"+this.country);
    }
}
public class Test{
    public static void main(String[] args){
        Person per = new Person("zhangsan", 20);
        per.getPersonInfo();
        Person.setCountry("中国");
        per.getPersonInfo();
    }
}

在这里插入图片描述
关于static方法有以下两点说明:

  1. 所有的static方法不允许调用非static定义的属性或方法
  2. 所有的非static方法允许访问static方法或属性

使用static定义的方法只有一个目的:某些方法不希望受到类的控制,即可以在没有实例化对象的时候执行(广泛存在于工具类中)。
注意:
  在一个静态方法中只能访问用static修饰的成员,原因在于没有被static修饰的成员需要先创建对象才能访问,而静态方法被调用时可以不创建任何对象。
  实例对象同样可以调用静态方法。

public class Test{
    public static void main(String[] args){
        //类名.方法的方式调用静态方法
        Person.setCountry("中国");
        Person per = new Person("zhangsan", 20);
        per.getPersonInfo();
        //实例化对象的方式来调用静态方法
        per.setCountry("China");
        per.getPersonInfo();
    }
}

运行结果如下所示:
在这里插入图片描述

由static修饰的还有代码块,称为 静态代码块, 这些我们在后面的总结会写到。