this关键字
- this是一个引用,this变量中保存的是内存地址指向自身,this存储在jvm的堆内存当中。
创建多少个对象,就有多少个this。
——见例一- this在多数情况下可以省略不写——见例二
- this不能使用在带有static的方法当中——见例二dosome
- 成员变量的理解与this——见例三
- 带有static的方法不能”直接“访问实例变量和实例方法,因为实例变量和实例方法都需要对象的存在。
而static的方法当中没有this,也就是当前对象不存在。
所以,在static当中,想访问实例变量、实例方法,需要new一个类对象——见例四 - 用来区分局部变量和实例变量的时候,this不能省略——见例五
- this使用范围: ——见例六【构造方法中】
- 1、可以使用在实例方法当中,代表当前对象——this.
- 2、可以使用在构造方法当中,通过当前构造方法调用其他构造方法——this(实参)
this()只能出现在构造函数的第一行;即在一个构造方法里面只能调用一次其他构造方法!!!
- 综合理解this——见例七
- 带有static 的方法既可以采用类名的方式访问,又可以使用引用的方式访问。即便是采用引用的方式,运行时是没有对象的参与的。
- 空指针异常问题:空引用访问实例相关的数据,因为实例数据是对象相关的数据。
这些数据在访问的时候,必须有对象的参与,当空引用时,对象不存在,此时访问实例数据,就会出现空指针异常。
例题一
- 创建多少个对象,就有多少个this
package day01.keywordthis;
/**
* @author 衣鱼
* this 关键字
*/
public class Customer {
//成员变量:姓名
String name;
//构造方法
public Customer(){
}
}
package day01.keywordthis;
public class CustomerTest {
public static void main(String[] args) {
//创建对象
Customer c1 = new Customer();
c1.name="靖远";
Customer c2 = new Customer();
c2.name="会宁";
}
}
不带static关键字的方法
当每一个行为/动作执行的过程当中是需要对象参与的,那么这个动作必须有对象的参与,不能带static关键字。
-
即:如果一个动作,不同对象导致的结果不同,那么这个动作就属于实例方法。
【你和世界上任意一个存活的人,过一年涨一岁。对象不同,结果一样】
【你和别人的工资、支出比较。对象不同,结果不同】
顾客购物的行为:每一个顾客购物的结果是不一样的
即购物行为属于对象级别的行为。 -
重点:
没有static关键字的方法被称为”实例方法“
没有static关键字的变量被称为”实例变量“ -
this在多数情况下可以省略不写
例题二
package day01.keywordthis;
/**
* @author 衣鱼
* this 关键字
*/
public class Customer {
//成员变量-实例变量:姓名
//调用:引用. 访问
String name;
//构造方法
public Customer(){
}
/**
* 不带有static关键字的方法
* 当每一个行为/动作执行的过程当中是需要对象参与的,那么这个动作必须有对象的参与,不能带static关键字。
* 即:如果一个动作,不同对象导致的结果不同,那么这个动作就属于实例方法。
* 【你和世界上任意一个存活的人,过一年涨一岁。对象不同,结果一样】
* 【你和别人的工资、支出比较。对象不同,结果不同】
* 顾客购物的行为:每一个顾客购物的结果是不一样的
* 即购物行为属于对象级别的行为。
* 重点:
* 没有static关键字的方法被称为”实例方法“
* 没有static关键字的变量被称为”实例变量“
*
*/
public void shopping() {
//System.out.println(name+"在购物!");
System.out.println(this.name+"在购物!");
}
//对比:带有static
public static void dosome() {
// System.out.println(name);报错
//因为name是实例变量,需要使用引用访问,而dosome是static,需要使用类名访问
//dosome方法不是实例去调用,而是类名去调用,执行过程中,没有当前对象的概念
}
}
package day01.keywordthis;
public class CustomerTest {
public static void main(String[] args) {
//创建对象
Customer c1 = new Customer();
c1.name="靖远";
Customer c2 = new Customer();
c2.name="会宁";
c1.shopping(); //shopping是没有static的方法,需要对象调用,即:引用.shopping()
c2.shopping();
//调用dosome方法:修饰符列表有static——类名.
//即:dosome方法在执行的时候,没有对象的参加
Customer.dosome();
}
}
考虑到:实例变量name访问的时候,就生成了一个引用,所以实例变量name访问的时候,一定访问的是当前对象的name,所以这个情况下,this是可以省略的。
例题三
package day01.keywordthis;
public class ThisTest {
//成员变量:静态变量
static int i =10;
//成员变量:实例变量
int c = 20;
/**
* 带有static方法,jvm的调用
* jvm负责调用main方法
* ThisTest.main(String[]); //类名.
* */
public static void main(String[] args) {
System.out.println(i);
//System.out.println(c); // 编译错误,需要访问当前对象c的属性
//访问实例变量:new一个对象
ThisTest t = new ThisTest();
System.out.println(t.c);
}
}
例题四
- 在static当中,想访问实例变量、实例方法,需要new一个类对象
package day01.keywordthis;
/**
* @author 衣鱼
* 结论:
* 带有static的方法不能”直接“访问实例变量和实例方法
* 因为实例变量和实例方法都需要对象的存在
* 而static的方法当中没有this,也就是当前对象不存在
* 所以,在static当中,想访问实例变量、实例方法,需要new一个类对象
*
*/
public class ThisTest01 {
//带有static 主方法
public static void main(String[] args) {
//调用dosome方法 :类名. [同类可以免去类名]
ThisTest01.dosome();
dosome();
//调用doother 调用当前对象的doother方法
//main方法中,没有this ,所以不能采用this.doother();
//doother d = new doother(); //创建一个对象,是类对象,而不是方法创建对象
ThisTest01 tt = new ThisTest01();
tt.doother();
//调用run
tt.run();
}
//带有static
public static void dosome() {
System.out.println("do some !");
}
//无static 实例方法 方法内含有this表示当前对象
public void doother() {
System.out.println("do other !");
}
//无static
public void run() {
System.out.println("run !");
doother(); //成功执行
//因为run是实例方法,需要有对象只能调用,当调用成功时,说明有对象创建
//那么,该对象会执行他所属的doother方法 this.doother()
}
}
例题五
- 用来区分局部变量和实例变量的时候,this不能省略
package day01.keywordthis;
/**
* @author 衣鱼
* this不能省略
* 用来区分局部变量和实例变量的时候,不能省略
*/
public class User {
//属性
private int id;
private String name;
//get set方法
/*版本一
* public void setId(int a){
id = a;
}
*/
//以下程序的id与实例变量的id无关,不能采用这个方式
/*版本二
* public void setId(int id) {
id = id;
}
*/
//版本三
public void setId(int id) {
//等号前面this.id是实例变量id
//等号后面的id是局部变量id
this.id = id; //this.id 就是 private int id的id;
}
//构造方法
//缺省
public User() {
}
//带参数
/*版本一
public User(int a,String s) {
id = a;
name= s;
}
*/
//版本二
public User(int id,String name) {
this.id = id;
this.name= name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
}
package day01.keywordthis;
public class UserTest {
public static void main(String[] args) {
//访问实例变量用户id new对象
//无参构造方法
User u = new User();
//有参构造方法
User u1 = new User(555,"乌兰");
System.out.println(u1.getName());
System.out.println(u1.getId());
u1.setName("祁连");
System.out.println(u1.getName());
}
}
例题六
this使用范围: 1、可以使用在实例方法当中,代表当前对象——this. 2、可以使用在构造方法当中,通过当前构造方法调用其他构造方法——this(实参) this()只能出现在构造函数的第一行;即在一个构造方法里面只能调用一次其他构造方法!!!
package day01.keywordthis;
/**
* @author 衣鱼
* 自定义的年月日
* this使用范围:
* 1、可以使用在实例方法当中,代表当前对象——this.
* 2、可以使用在构造方法当中,通过当前构造方法调用其他构造方法——this(实参)
* this()只能出现在构造函数的第一行;即在一个构造方法里面只能调用一次其他构造方法!!!
*/
public class Data {
//属性
private int year;
private int month;
private int day;
//构造函数
//缺省
/**
* 需求:当程序员调用以下无参数的构造方法的时候,默认创建的日期1970-1-1
*/
public Data() {
/* 版本一:
this.year = 1970;
this.month = 1;
this.day = 1;
*/
//以上代码可以通过调用另外一个构造方法来完成,但前提是不能创建新对象 new Date(1970,1,1);
//版本二:精简了代码,但是创建了新对象
//new Date(1970,1,1);
//版本三 :精简代码,没有创建新对象
//使用以下方法完成构造方法的调用
//这种方法不会创建新的java对象,但同时又可以达到调用其他的构造方法。
this(1970,1,1);
/**
* 需求代码实现总结:
* 为了精简代码,在一个构造函数之内可以调用另外一个构造函数,达到代码片的重复利用
* 构造函数的调用,一般需要new一个对象。但是在main函数里已经创建了一个date对象,再创建对象,是我们不想看到的
* 一个构造函数调用另外一个构造函数,且不创建对象!这是我们希望的
* java也为我们提供了这样的方法:this();
*
*/
}
//含参
public Data(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
//对外提供一个方法将日期打印输出到控制台
//实例方法
public void print() {
System.out.println(this.year+"年"+this.month+"月"+this.day+"日");
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
}
package day01.keywordthis;
public class DataTest {
public static void main(String[] args) {
//输出打印
//创建对象
Data time1 = new Data();
time1.print();
//创建对象 含参
Data time2 = new Data(2021,6,17);
time2.print();
System.out.println("今天是2021年6月17日!上午9时22分27秒神舟十二升空,9时42分飞行成功");
}
}
例题七
- this综合理解
package day01.keywordthis;
public class Test03 {
//不带static的变量
int i = 10;
//带有static的方法
public static void dosome() {
System.out.println("dosome !");
}
//不带static的方法
public void doother() {
System.out.println("doother !");
}
public static void method01() {
//调用dosome:完整方式、省略方式[没有省略方式,不写]
//调用doother:完整方式、省略方式
Test03.dosome();
dosome();
Test03 aa = new Test03();
aa.doother();
}
public void method02() {
//调用dosome:完整方式、省略方式
//调用doother:完整方式、省略方式
Test03.dosome();
dosome(); //当前对象的dosome方法,对象是可以调用static方法的
//见下一个代码块
Test03 bb =new Test03();
bb.doother();
this.doother();
}
public static void main(String[] args) {
/*
* 要求:
* 调用method01:使用完整方式调用;使用省略方式调用
* 调用method02
* 访问i
* */
Test03.method01();
method01();
Test03 tt = new Test03(); //static无this
tt.method02();
//调用i
//i是无static的变量,是成员变量里面的实例变量,需要使用对象调用
Test03 cc = new Test03();
System.out.println(cc.i);
}
}
package day01.keywordthis;
/**
* @author 衣鱼
* 空指针异常问题
* 空引用访问实例相关的数据,因为实例数据是对象相关的数据
* 这些数据在访问的时候,必须有对象的参与,当空引用时,对象不存在
* 此时访问实例数据,就会出现空指针异常。
*
* 实例数据
* 实例方法;实例变量
*
* 带有static 的方法既可以采用类名的方式访问,又可以使用引用的方式访问。即便是采用引用的方式,运行时是没有对象的参与的
*/
public class Test031 {
public static void main(String[] args) {
Test031.dosome();
dosome();
Test031 tt = new Test031();
tt.dosome(); //带有static的方法,引用依旧可以运行
tt = null; //空指针,仍可以运行:说明运行没有使用对象
tt.dosome();
}
public static void dosome() {
System.out.println("dosome!");
}
}