太原理工大学机器人团队20天学习打卡day16
今天将继续学习this关键字的剩余内容以及static关键字
1、this关键字
①this什么时候不能省略?
通过昨天的学习我们知道this可以省略,那么什么时候不能省略呢,看下面的例子
//用户类
public class User {
//属性
private int id;//实例变量
private String name;
//构造函数
public User(){
}
/*
public User(int a,String s){
id = a;
name = s;
}
*/
public User(int id,String name){
this.id = id;
this.name = name;
}
//setter and getter
/*
public void setId(int a){
id = a;
}
*/
//以下程序的id和实例变量无关,不能采用这种方式
/*
public void setId(int id){
id = di;
}
*/
public void setId(int id){
//等号前面的this.id是实例变量id
//等号后面的id是局部变量id
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
}
结论
- 用来区分局部变量和实例变量的时候 this. 不能省略
测试【基于上面的代码】
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());
//想修改名字
u1.setName("lisi");
System.out.println(u1.getName());
}
}
②用this调用构造方法
//自定义的日期类型
public class Date {
//属性
private int year;
private int month;
private int day;
//setter and getter
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;
}
//构造函数
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;
*/
//以上代码可以通过调用另一个构造方法来完成
//但前提是不能创建新的对象,以下代码表示创建了一个全新的对象
//new Date(1970,1,1);
//需要采用以下的语法来完成构造方法的调用
//这种方式不会创建新的java对象,但同时又可以调用其他的构造方法
this(1970,1,1);
}
//对外提供一个方法可以将日期打印输出到控制台
//实例方法
public void print(){
System.out.println(this.year+"年"+this.month+"月"+this.day+"日");
}
}
public class DataTest {
public static void main(String[] args) {
//创建日期对象1
Data time1 = new Date();
time1.print();
//创建日期对象2
Data time2 = new Date(2008,8,8);
time2.print();
}
总结:this可以用在哪里
- 使用在实例方法当中,代表当前对象【语法格式
this.
】 - 使用在构造方法当中,通过当前的构造方法调用其他构造方法【语法格式
this(实参);
】- 注意:this()这种语法只能出现在构造函数第一行
2、static关键字
①引例
public class Chinese {
//身份证号【每一个对象的身份证号不同】
String id;
//姓名【每一个对象的姓名不同】
String name;
//国籍【每一个对象由于都是由“Chinses”这个类实例化的,所以每一个对象的国际都是中国
//无论通过“Chinese”这个类实例化多少个java对象,这些java对象的国籍都是中国
//实例变量【一个java对象就有一个,100个java对象就有100个】,分析这种方式有什么缺点
//所有的中国人的国籍都是中国,这里声明为实例变量显然是不合适的,太浪费内存空间,没必要让每一个对象都保留一份国籍内存
//String country;
//所有对象的国籍一样,这个特征属于类级别的特征,可以提升为整个模板的特征,可以加上static修饰
//静态变量,在类加载的时候初始化,不需要创建对象,内存就开辟了
//静态变量储存在方法区内存当中
static String country = "中国";
//构造函数
public Chinese(){
/*
this.id=null;
this.name=null;
this.country=null;
*/
}
public Chinese(String id,String name){
this.id = id;
this.name = name;
}
}
public class ChineseTest {
public static void main(String[] args) {
//创建中国人对象1
Chinese zhangsan = new Chinese("1","张三");
System.out.println(zhangsan.id+","+zhangsan.name+","+Chinese.country);
//创建中国人对象2
Chinese lisi = new Chinese("2","李四");
System.out.println(lisi.id+","+lisi.name+","+Chinese.country);
System.out.println(zhangsan.country);
zhangsan = null;
//所有的静态的数据都是可以采用类名.也可以采用引用.但是建议采用类名.的方式访问
//采用引用.的方式访问的时候,即使引用时null,也不会出现空指针异常。因为静态的数据不需要对象的存在
System.out.println(zhangsan.country);
}
}
②什么时候成员变量声明为实例变量呢
- 所有对象都有这个属性,但是这个属性的值会随着对象的变化而变化【不同对象的这个属性具体的值不同】
③什么时候成员变量声明为静态变量呢
- 所有对象都有这个属性,并且所有对象的这个属性的值是一样的,建议定义为静态变量,节省内存空间
④static
- static英语单词翻译为静态的
- static修饰的方法时静态方法
- static修饰的变量是静态变量
- 静态变量在类加载的时候初始化,内存在方法区中开辟。访问的时候不需要创建对象,直接使用类名.静态变量名的方式访问
- 所有static修饰的元素都称为静态的,都可以使用**类名.**的方式访问,当然也可以使用引用.的方式访问,但不建议
- static修饰的所有元素都是类级别的特征,和具体的对象无关
⑤使用static定义静态代码块
语法格式
static{
java语句;
}
语法规则
- 静态代码块在类加载时执行,并且只执行一次
- 静态代码块在一个类中可以编写多个,并且遵循自上而下的顺序依次执行【一般只写一个,几个都可以放在一个中】
静态代码块的作用
- 和具体需求有关,例如项目要求在类加载的时刻完成日志的记录,那么这段记录日志的代码就可以编写到静态代码块当中,完成日志的记录
- 静态代码块是java程序员准备的一个特殊时刻,这个特殊的时刻被称为类加载时刻。若希望在此刻执行一段特殊的程序,这段程序可以直接放到静态代码块当中
⑥方法什么时候定义成静态的
- 方法描述的是动作,当所有的对象执行这个动作的时候,最终产生的影响是一样的,那么这个动作已经不再属于某一个对象动作了,可以将这个动作提升为类级别的动作,模板级别的动作
- 静态方法中无法直接访问实例变量和实例方法
- 大多数方法都定义为实例方法,一般一个行为或者一个动作在发生的时候,都需要对象的参与。但是也有例外,例如大多数工具类方法都是静态方法,因为工具类就是方便编程,为了方便方法的调用,自然不需要new对象是最好的