Java中this关键字和static关键字

Java 同时被 2 个专栏收录
70 篇文章 2 订阅
53 篇文章 2 订阅

1. this关键字

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

  1. this表示本类属性。
  2. this表示本类方法。
  3. this表示当前对象。

1.1 this表示本类属性

观察以下代码:

class Person{
    private String name;
    private int age;
    //构造函数
    public Person(String name,int age)
    {
        name=name;
        age=age;
    }
    public void work()
    {
        System.out.println(name+"在工作!");
    }
    public  void  age()
    {
        System.out.println(name+age+"岁了!");
    }
}
public class Test{
    public static void main(String[] args)
    {
       Person per1=new Person("花花",-18);
        per1.work();
        per1.age();
    }
}

执行结果:
null在工作!
null0岁了!
  通过以上代码,我们发现当参数与类中的属性同名时,类中的属性无法被正确赋值(根据就近使用原则,相当于自己=自己)。此时我们加上this关键字便可以正确给对象属性赋值。

class Person{
    private String name;
    private int age;
    //构造函数
    public Person(String name,int age)
    {
        this.name=name;
        this.age=age;
    }
    public void work()
    {
        System.out.println(name+"在工作!");
    }
    public  void  age()
    {
        System.out.println(name+age+"岁了!");
    }
}
public class Test{
    public static void main(String[] args)
    {
       Person per1=new Person("花花",18);
        per1.work();
        per1.age();
    }
}

在这里插入图片描述
所以只要在类中访问类的属性,一定要加上this关键字

1.2 this调用本类方法

1.2.1 this调用普通方法

格式:this.方法名称(参数)

class Person{
    private String name;
    private int age;
    //构造函数
    public Person(String name,int age)
    {
        this.name=name;
        this.age=age;
        this.work();
    }
    public void work()
    {
        System.out.println(name+"在工作!");
    }
    public  void  age()
    {
        System.out.println(name+age+"岁了!");
    }
}
public class Test{
    public static void main(String[] args)
    {
       Person per1=new Person("花花",18);
    }
}

在这里插入图片描述
  虽然调用本类的普通方法不需要加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());
	}
}

执行结果:
******** 产生一个新的Person对象********
******** 产生一个新的Person对象********
******** 产生一个新的Person对象********
姓名:null,年龄:0
姓名:张三,年龄:0
姓名:李四,年龄:20
  上述代码编译执行没有问题,但有大量的重复代码,在java中不允许有重复代码的出现。那怎么解决呢?
在Java中,支持构造方法的互相调用。
修改上述代码:

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(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());
	}
}

执行结果:
******** 产生一个新的Person对象********
******** 产生一个新的Person对象********
******** 产生一个新的Person对象********
姓名:null,年龄:0
姓名:张三,年龄:0
姓名:李四,年龄:20
使用this调用构造方法时请注意:

  1. this调用构造方法的语句必须在构造方法的首行。
  2. this调用构造方法不允许成环。
    在这里插入图片描述

1.2.3 this表示当前对象

class Person{
	private String name;
	private int age;

	public Person(String name,int age){
        this.name = name;
		this.age = age ;
	}
	public void getPersonInfo(){
		System.out.println(this +" 姓名:" + name + ",年龄:"+age);
	}
}
public class Test{
		public static void main(String[] args) {
			Person per1 = new Person("李四",17);
		    System.out.println("&per1="+per1);
            per1.getPersonInfo();
			Person per2 = new Person("张三",18);
            System.out.println("&per2="+per2);
            per2.getPersonInfo();
	}
}

在这里插入图片描述

2. static关键字

2.1 static修饰属性

观察此段代码:

class Person{
	private String name;
	private int age;
    private String schoolName;
	//构造方法
    public Person(String name, int age, String schoolName)
    {
        this.name=name;
        this.age=age;
        this.schoolName=schoolName;
    }
    public void getPeopleInfo()
    {
        System.out.println("学校:"+schoolName+"  姓名:"+name+" 年龄:"+age);
    }
}
public class Test{
		public static void main(String[] args) {
		Person per1=new Person("张三",18,"励志中学");
		Person per2=new Person("李四",17,"励志中学");
        per1.getPeopleInfo();
        per2.getPeopleInfo();
	}
}

内存分析图:
在这里插入图片描述
  一个学校里有成千上万个学生,虽然名字各不相同,但是学校名称却是相同的,像上图那样保存学生的信息,会造成系统资源的大量浪费。
若想要描述共享属性,只需在属性前添加static关键字即可。
修改上述代码:public static String schoolName=“励志中学”; //static之前必须用public修饰

class Person{
	private String name;
	private int age;
    public static String schoolName="励志中学";
    
    public Person(String name, int age)
    {
        this.name=name;
        this.age=age;
    }
    public void getPeopleInfo()
    {
        System.out.println("学校:"+schoolName+"  姓名:"+name+" 年龄:"+age);
    }
}
public class Test{
		public static void main(String[] args) {
		Person per1=new Person("张三",18);
		Person per2=new Person("李四",17);
        per1.getPeopleInfo();
        per2.getPeopleInfo();
        System.out.println(Person.schoolName);
	}
}

在这里插入图片描述
此时的内存分析图如下:
在这里插入图片描述
  static修饰的属性称为类属性,保存在全局数据区中(方法区-所有对象的共享区域),通过类名调用,与对象实例化无关。
类属性是在类加载的时候初始化,而且只被初始化一次。在程序中任何对象对静态变量做修改其他对象看到的是修改后的值。
结论:

  • 访问static属性(类属性)应使用 类名称.属性名
  • 所有的非static属性必须在对象实例化后使用,而static属性(类属性)不受对象实例化的控制。

2.2 static修饰方法

通过类名调用,与对象实例化无关,常用于工具类方法。
典型的静态方法:
i.Arrays.sort(数组名称) 数组排序
ii.System.arraycopy(源数组名称,源数组开始点,目标数组名称,目标数组开始点,拷贝个数) 数组拷贝
iii.Arrays.copyOf(源数组名称,目标数组长度) 数组全拷贝

class Person{
	private String name;
	private int age;
    public static String schoolName;
   
    public Person(String name, int age)
    {
        this.name=name;
        this.age=age;
    }
	//静态方法
    public static void setschoolName(String n)
    {
        schoolName=n;
    }
    public void getPeopleInfo()
    {
        System.out.println("学校:"+schoolName+"  姓名:"+name+" 年龄:"+age);
    }
}
public class Test{
		public static void main(String[] args) {
		//直接通过类名调用与对象无关
        Person.setschoolName("励志中学");    
		Person per1=new Person("张三",18);
		Person per2=new Person("李四",17);
        per1.getPeopleInfo();
        per2.getPeopleInfo();
	}
}

在这里插入图片描述
关于static方法的说明:

  • static修饰的方法允许调用任何static修饰的属性或方法,但是不能调用非static修饰的属性或方法
  • 局部变量(方法中的变量)不能用static修饰
  • static方法就是没有this的方法,静态方法不依赖于任何对象就可以进行访问,它不依赖于任何对象,就谈不上this了

2.2 static修饰代码块

static关键字修饰的代码块叫做 静态代码块
根据静态代码块位置的不同又分为:主类中的静态代码块非主类中的静态代码块

2.2.1 非主类中的静态代码块

class Person{
    public Person(){
        //构造方法
        System.out.println("Person 类的构造方法");
    }
    {
        //构造块
        System.out.println("Person 类的构造块");
    }
    static {
        //静态块
        System.out.println("Person 类的静态代码块");
    }
}
public class Test{
    public static void main(String[] args)
    {
        new Person();
        new Person();
    }
}

在这里插入图片描述
由此可见,非主类中的静态代码块优先于构造块执行(构造块是不加任何修饰符的代码块,优先于构造方法执行,产生几个对象,就执行几次构造方法),且无论产生多少对象,静态代码块只执行一次。

2.2.2 主类中的静态代码块

public class Test{
    public Test()
    {
        //构造方法
       System.out.println("主类的构造方法");
    }
    {
        //构造块
       System.out.println("主类的构造块");
    }
    static {
        //静态块
        System.out.println("主类的静态代码块");
    }
    public static void main(String[] args)
    {
        System.out.println("start....");
        new Test();
        new Test();
        System.out.println("end.....");
    }
}

在这里插入图片描述
由此可见,主类中的静态代码块优先于主方法执行,即JVM一启动便执行。

  • 14
    点赞
  • 0
    评论
  • 16
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值