写在前面
下面主要记录一下this指针和static关键字修饰的类没有this指针等情况
目录
- this关键字
- static关键字
开始
先来一个小栗子
- Monkey类
import java.time.ZoneOffset;
/**
* @author 司超龙
*
*/
public class Monkey {
//静态成员变量
private static String zoo = "花果山";
//普通成员变量
private String name;
private int age;
private double weight;
public Monkey() {
// TODO Auto-generated constructor stub
}
public Monkey(String name, int age, double weight) {
super();
this.name = name;
this.age = age;
this.weight = weight;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public double getWeight() {
return weight;
}
public static String getZoo() {
return zoo;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setWeight(double weight) {
this.weight = weight;
}
public static void setZoo(String zoo) {
Monkey.zoo = zoo;
}
//普通成员方法
public void run(String name) {
System.out.println(this.name + " 跑起来了~~");
}
public void eat() {
System.out.println(this.name + " 正在吃香蕉~~");
}
//静态成员方法
public static void sleep() {
System.out.println("我睡着了");
}
/**
* 下面代码报错
* @param name
*/
/*
public static execrise(String name) {
System.out.println(this.name + " 在锻炼!!是一个自律猴~");
}
*/
}
- 测试Main类
public class ThisZhiZhen {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建猴子a
Monkey aMonkey = new Monkey("xiaosi",19,50);
//创建猴子b
Monkey bMonkey = new Monkey("si",20,51);
//调用普通无参成员方法
aMonkey.eat();
bMonkey.eat();
System.out.println("===========");
//调用有参普通成员方法
aMonkey.run(aMonkey.getName());
bMonkey.run(bMonkey.getName());
System.out.println("============");
//分别使用类名、对象名,获取静态成员变量
System.out.println(Monkey.getZoo());
//使用对象名获取静态成员变量,虽然不算错,但是不建议
System.out.println(aMonkey.getZoo());
System.out.println(bMonkey.getZoo());
//使用某一个对象名,修改静态成员变量,不能算错,但是不建议
aMonkey.setZoo("开封动物园");
//再次打印,发现全部改变
System.out.println(Monkey.getZoo());
System.out.println(aMonkey.getZoo());
System.out.println(bMonkey.getZoo());
System.out.println("==============");
//使用对象名,调用静态成员方法,不能算错,但是不建议
aMonkey.sleep();
bMonkey.sleep();
System.out.println("============");
}
}
由上面的代码我们可以看出来:
- 对象名、类名都可以调用 静态无参成员方法,获取静态成员变量、设置静态成员变量(只不过是对象名调用不太建议,因为上篇博客也提到,static修饰的方法、属性,就属于这个类对象的了,不在属于实例化对象个体得了)
- 对象名可以调用 无参、有参 普通成员方法,对于有参的成员方法调用,需要传入实例化对象的参数
我们都知道,每个实例化对象都有 属于 自己的 普通成员变量,这很容易理解,但是 那些普通的成员 方法呢?
是每个对象都有属于自己的一份呢,还是只有 类中的单独一份,或者这样说,每个实例对象堆区内存空间,是否都包含类内的普通成员方法呢?
答案当然是 只有一份,所有的实例对象调用的都是类内的方法
那么问题又来了,既然多个对象调用的是类内的同一个方法,那么怎么区分是哪个对象调用的呢?、
这就是this指针的功能了
一、this关键字
this
关键字,也称为了this
指针,就是指向实例化对象堆区的地址,类似的还有super关键字等
this
指针可以理解为 就是 当前 使用者 的 一个 别名
因为实例对象可以有很多,理想状态每个实例对象都有相同的方法(技能),属性可能不太相同,因此只需要 把 个性的 特征单独存储,对于一致的方法(技能)就不需要在浪费空间,共享出来共所有实例对象需要时调用即可(封装)
这些共享的方法,就需根据this区分不同的调用者,看下面代码
public void eat() {
System.out.println(name + " 正在吃香蕉~~");
}
/*
* 和上面效果相同
public void eat() {
System.out.println(this.name + " 正在吃香蕉~~");
}
*/
/*
* public void run( String name) {
System.out.println(this.name + " 跑起来了~~");
和下面效果相同
}
*/
public void run( String name) {
System.out.println(name + " 跑起来了~~");
}
因此对于非静态成员方法,在实例对象调用他们的时候,都会有一个默认的参数this,只不过我们有时看不见他们
但是,编译器一定可以看见他们
public void eat(this) {
System.out.println(this.name + " 正在吃香蕉~~");
}
//调用普通无参成员方法
aMonkey.eat();
bMonkey.eat();
/*
* 相当于
* eat(aMonkey)
* eat(bMonkey)
*
*/
public void run( String name) {
System.out.println(name + " 跑起来了~~");
}
/*
* public void run(this, String name) {
System.out.println(this.name + " 跑起来了~~");
}
*/
//调用有参普通成员方法
aMonkey.run(aMonkey.getName());
bMonkey.run(bMonkey.getName());
/*
* run(this,this.getName)
* run(aMonkey,aMonkey.getName());
* run(bMonkey,bMonkey.getName());
*
*/
关于this参数,默认被编译器缺省
对于static修饰的成员变量、成员方法有没有这个this指针呢?
答案是没有
二、static关键字
更多参考:菜鸟教程
也就是说
- 静态成员变量在内存中只有一份,可以通过对象名访问,但是不建议,一般通过类名设置,访问
- 静态成员方法没有this指针,不能使用类的非静态变量,因为类的非静态变量值 是属于 实例对象的,值是不确定的
/**
* 报错!!
* @param name
*/
public static execrise(String name) {
System.out.println(this.name + " 在锻炼!!是一个自律猴~");
}
/*
execrise()
execrise(aMonkey)//参数多了好办,不用传下去,直接丢弃
execrise(aMonkey)//参数多了好办,不用传下去,直接丢弃
*/