关于JAVA中this关键字:
1、this是一个关键字;
2、this是一个引用,是一个变量,this变量保存的是内存地址,指向的是自己,this存储在JVM堆内存java对象内部;
3、创建100个java对象,每一个对象都有this,也就是说100个不同的this
public class Customer {
String name;
public Customer(){
}
}
public class This01 {
public static void main(String[] args){
Customer c1 = new Customer();
c1.name = "zhangsan";
Customer c2 = new Customer();
c2.name = "lisi";
}
}
public class Customer {
String name;
public Customer(){
}
//不带static的一个方法
//顾客的购物行为
//没一个顾客购物的最终的结果是购买不一样的
//所以购物这个行为是属于对象级的行为
//由于每一个对象在执行购物这个方法的时候最终结果是不同的,所以这个动作必须是有“对象”的参与
//重点:没static关键字的方法称为“实例方法”;实例方法怎么访问:“引用.”
//重点:没static关键字的变量称为“实例变量”
//当一个行为/动作执行的过程中需要对象参与的,那么这个方法一定要定义为“实例方法”,不用带static
public void shopping(){
System.out.println(name+"在购物");
}
}
public class This01 {
public static void main(String[] args){
Customer c1 = new Customer();
c1.name = "zhangsan";
c1.shopping();
Customer c2 = new Customer();
c2.name = "lisi";
c2.shopping();
}
}
但是name是实例变量,必须采用“引用.”的方法来访问
所以完整写法:
public void shopping(){
//System.out.println(name+"在购物");
//完整写法
System.out.println(this.name+"在购物");
}
4、this可以出现在实例方法中,指向当前执行这个动作的对象(上文例子中c1或者c2,取决于处于在哪个对象之中)。
5、this在多数情况下可以省略不写的。
this代表当前的对象。
下一个例子:
public class This01 {
public static void main(String[] args){
Customer c1 = new Customer();
c1.name = "zhangsan";
c1.shopping();
Customer c2 = new Customer();
c2.name = "lisi";
c2.shopping();
//调用doSome方法
//类名.方法名
Customer.doSome();
}
}
编译错误
为啥编译错误呢?
doSome方法的调用不是对象去调用而是一个类名去调用,执行过程中没有“当前对象”;
name是一个实例变量,以下代码含义是访问当前对象的name,没有当前对象,自然也不能访问当前对象的name;
System.out.println(name);
static的方法不需要对象,直接使用类名,
6、this不能使用在带有static的方法中
举个栗子:
public class ThisTest {
public static void main(String[] args){
ThisTest.doSome();
doSome();
ThisTest tt = new ThisTest();
tt.doOther();//实例方法的调用必须有对象的存在
}
//带有static
public static void doSome(){
System.out.println("do Some!");
}
//实例方法
public void doOther(){
//this表示当前对象
System.out.println("do Other!");
}
}
但是:
public class ThisTest {
public static void main(String[] args){
ThisTest.doSome();
doSome();
ThisTest tt = new ThisTest();
tt.doOther();//实例方法的调用必须有对象的存在
tt.run();
}
//带有static
public static void doSome(){
System.out.println("do Some!");
}
//实例方法
public void doOther(){
//this表示当前对象
System.out.println("do Other!");
}
//实例方法,run是实例方法,调用run方法的一定是有对象存在的
//一定是先创建了一个对象才能调用run方法
public void run(){
//在大括号中的代码执行过程中一定是存在“当前对象”的
//也就是说这里一定有this的
System.out.println("run execute!");
//doOther方法是一个实例方法,实例方法调用必须有当前对象的存在
//以下代码表示的含义就是:调用当前对象的doOther()方法
doOther();
this.doOther();//完整写法,this可省略,上面调用的时候是“tt”,所以这里的this就是表示“tt”
}
}
总结: 带有static的方法中不能直接访问实例变量和实例方法。
因为实例变量和实例方法都需要对象的存在。
而static方法中是没有this的,也就是说当前的方法不存在的。
自然也无法访问当前对象的实例变量和实例方法。
this什么时候不能省略?
用来区分局部变量和实例变量的时候,this不能省略。
public class User {
private int id;
private String name;
//构造函数
public User(){
}
public User(int id, String name) {
this.id = id;
this.name = name;
}
public void setId(int id){
this.id = id;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class UserTest {
public static void main(String[] args){
User u1 = new User(100,"zhangsan");
System.out.println(u1.getId());
System.out.println(u1.getName());
//假如想改名字,用到了set方法
u1.setName("lisi");
System.out.println(u1.getName());
}
}
举例子:
package This;
public class Date {
private int year;
private int month;
private int day;
//构造器
public Date(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
/**
* 需求:
* 当程序员调用以下无参数的构造方法时,默认创建日期为“1970-1-1”
* */
public Date() {
this.year = 1970;
this.month = 1;
this.day = 1;
}
//get和set方法
public void setYear(int year) {
this.year = year;
}
public void setMonth(int month) {
this.month = month;
}
public void setDay(int day) {
this.day = day;
}
public int getYear() {
return year;
}
public int getMonth() {
return month;
}
public int getDay() {
return day;
}
//对外提供一个方法可以将日期打印在控制台
//实例方法
public void print(){
System.out.println(this.year+"年"+this.month+"月"+this.day+"日");
}
}
package This;
public class DayTest {
public static void main(String[] args){
//创建日期对象1
Date time1 = new Date();
time1.print();
//创建日期对象2
Date time2 = new Date(2008,8,8);
time2.print();
}
}
其中,简化书写,无参数构造器可以改成:
public Date() {
/*this.year = 1970;
this.month = 1;
this.day = 1; */
//以上方法可以通过调用另一个构造方法来完成
//但是前提是不能创建新的对象,比如创建对象new Date(1970,1,1)不可以;
//需要采用以下的语法来完成构造方法的调用
//这种方法不会创建新的java对象,但同时又可以达到调用其他构造方法
this(1970,1,1);//必须是构造方法的第一行
}
this可以用在哪里?
1、可以使用在实例方法之中,代表当前对象【this. 】
2、可以使用在构造方法之中,通过当前的构造方法调用其他的构造方法【this(实参);】注意:必须是构造方法的第一行
public class ThisTest {
//带有static的方法
public static void method1(){
//完整的方式调用doSome
ThisTest.doSome();
//省略的方式调用doSome
doSome();
//完整的方式调用doOther
ThisTest tt = new ThisTest();
tt.doOther();
//省略的方式调用doOther
//完整方式访问i
ThisTest tt2 = new ThisTest();
int j = tt2.i;
//省略方式访问i
}
//没有static的方法
public void method2(){
//完整的方式调用doSome
ThisTest.doSome();
//省略的方式调用doSome
doSome();
//完整的方式调用doOther
ThisTest tt3 = new ThisTest();
tt3.doOther();
//省略的方式调用doOther
this.doOther();
//完整方式访问i
System.out.println(this.i);
//省略方式访问i
System.out.println(i);
}
//主函数
public static void main(String[] args){
//完整的方式调用method1
ThisTest.method1();
//省略的方式调用method1
method1();
//完整的方式调用method2
ThisTest t = new ThisTest();
t.method2();
//省略的方式调用method2
}
//没有static的变量
int i = 10;
//有static的方法
public static void doSome(){
System.out.println("do Some!");
}
//没有static的方法
public void doOther(){
System.out.println("do Other!");
}
}
什么时候运行时出现空指针异常?
空引用访问实例相关的数据,因为实例相关的数据就是对象的数据;这些数据在被访问的时候,一定要有对象的参与,当空引用的时候,对象不存在,这些实例数据就会空指针异常。
实例相关的数据包括实例变量和实例方法【对象需要存在】
public class ThisTest2 {
public static void main(String[] args){
ThisTest2.doSome();
doSome();
ThisTest2 t = new ThisTest2();
t.doSome();
t = null;
t.doSome();//带有static的方法调用时候既可以类名方式访问也可以是这样的引用的方式调用,但是引用的方式,但是实际上与对象无关,所以还是建议类名方式引用
}
//带有static的方法调用时候是 "类名." 引用方式
public static void doSome(){
System.out.println("doSome!");
}
}
但是这里的t对象是空,却没有运行异常
因为这里的 t.doSome() 中引用这个方法和对象没关系。