文章目录
1. this关键字
this关键字主要有以下三个方面的用途:
- this调用本类属性
- this调用本类方法
- this表示当前对象
1.1 this调用本类属性
先看一段代码:
class Person{
private String name;
private int age;
public Person(String name, int age)
{
name = name;
age = age;
}
public String getPersonInfo()
{
return "姓名:" + name + " 年龄:" + age;
}
}
public class Test{
public static void main(String[] args){
Person per = new Person("张三", 20);
System.out.println(per.getPersonInfo());
}
}
运行结果如下:
大家会发现,明明实例化对象时,Person(“张三”, 20); 但是得出的结果却是不是我们想要的结果。我们再看构造方法有了下面的代码:
name = name;
age = age;
通过以上代码我们可以发现,当参数中属性同名是,类中属性无法被正确赋值。此时我们加上this关键字便可正确给对象属性赋值。
this.name = name;
this.age = age;
只要在类中方法访问类中属性,一定要加上this关键字。
1.2 this调用本类方法
this调用本类方法有一下两种情况:
- 调用普通方法
- 调用构造方法
1.2.1 this调用普通方法
举例:
class Person{
private String name;
private int age;
public Person(String name, int age)
{
this.name = name;
this.age = age;
this.print();//调用普通方法
}
public String getPersonInfo()
{
return "姓名:" + name + " 年龄:" + age;
}
public void print()
{
System.out.println("*******************");
}
}
public class Test{
public static void main(String[] args){
Person per = new Person("张三", 20);
System.out.println(per.getPersonInfo());
}
}
运行结果如下:
虽然调用本类普通方法不需要加上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());
}
}
上述代码在构造方法中出现了一些代码重复问题,想要解决此类问题,就需要用到this.
在Java中,支持构造方法的互相调用(this)。
修改代码如下:
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();//调用本类有一个参数的构造方法
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());
}
}
运行结果如下:
使用this调用构造方法时请注意:
- 只能在构造方法中使用this调用其他的构造方法,不能再成员方法中使用。
- 在构造方法中,使用this调用构造方法的语句必须位于第一行,且只能出现一次。下面的写法时非法的,必须在写代码时注意。
Public Person(String name, int age) {
this.age = age;
this(name); //调用有参的构造方法。由于不在第一行,编译错误。
}
运行结果如下:
- 不能在一个类的两个构造方法中使用this互相调用,下面的写法编译会报错。
public Person(){
this("lisi");//调用有参的构造方法
System.out.println("****无参构造****");
}
public Person(String name){
this(); //调用无参的构造方法
System.out.println("****有参构造****");s
}
运行结果如下:
1.3 this表示当前对象
举例:this表示当前对象
class Person{
public void print(){
System.out.println("[PRINT]方法:" + this);
}
}
public class Test{
public static void main(String[] args){
Person per1 = new Person();
System.out.println("[MAIN]方法: " + per1);
per1.print();
System.out.println("************************");
Person per2 = new Person();
System.out.println("[MAIN]方法: " + per2);
per2.print();
}
}
只要调用了本类中的方法,这个this就表示当前执行的对象。
2. static关键字
在Java类中定义了一个static关键字,它用于修饰类的成员,如成员变量、成员方法以及代码块等。
2.1 static属性(类属性)
在定义一个类时,只是在描述某类事物的特征和行为并没有产生具体的数据。只有通过new关键字创建该类的实例对象后,系统才会为每个对象分配内存空间,存储各自的数据。
但是有时候需要某些特定的数据在内存中只有一份,而且能够被一个类的所有实例对象所共享。
举例:实例属性的内存分析
class Person{
String country = "中国";
String name;
int age;
public void getPersonInfo(){
System.out.println("姓名:" + this.name + ",年龄:" + this.age + ",国家:" + this.country);
}
}
public class Test{
public static void main(String[] args){
Person per1 = new Person();
per1.name = "zhangsan";
per1.age = 10;
Person per2 = new Person();
per2.name = "lisi";
per2.age = 20;
per1.getPersonInfo();
per2.getPersonInfo();
}
}
运行结果如下:
内存分析图如下:
传统属性所具备的特征:保存在堆内存中,且每个对象独享属性。
描述共享属性,只需在属性前添加static关键字即可。
static属性又称为类属性,保存在全局数据区的内存之中,所有对象都可以进行该数据区的访问。
修改上述代码:
此时的内存分析图如下所示:
结论:
- 访问static属性应使用 类名称 . 属性名
- 所有的非static属性(实例变量)必须在对象实例化后使用,而static属性不收对象实例化控制
- 修改static属性,所有对象都同步此属性。应使用一下方法修改:
定义类时,如何选择实例变量和类属性呢?
- 在定义类时,99%的情况都不会考虑static属性,以非static属性(即实例变量)为主
- 如果需要描述共享属性的概念,或者不受对象实例化控制,使用static
注意:
static关键字只能用于修饰成员变量,不能用于修饰局部变量,否则编译会报错,下面代码时非法的:
2.2 static方法(类方法)
使用static定义的方法,直接通过类名进行访问。
类名称 . 方法名
举例:观察static方法
class Person{
private static String country;
private String name;
private int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
public static void setCountry(String s){
country = s;
}
public void getPersonInfo(){
System.out.println("姓名:"+this.name+",年龄:"+this.age+"国家:"+this.country);
}
}
public class Test{
public static void main(String[] args){
Person per = new Person("zhangsan", 20);
per.getPersonInfo();
Person.setCountry("中国");
per.getPersonInfo();
}
}
关于static方法有以下两点说明:
- 所有的static方法不允许调用非static定义的属性或方法
- 所有的非static方法允许访问static方法或属性
使用static定义的方法只有一个目的:某些方法不希望受到类的控制,即可以在没有实例化对象的时候执行(广泛存在于工具类中)。
注意:
在一个静态方法中只能访问用static修饰的成员,原因在于没有被static修饰的成员需要先创建对象才能访问,而静态方法被调用时可以不创建任何对象。
实例对象同样可以调用静态方法。
public class Test{
public static void main(String[] args){
//类名.方法的方式调用静态方法
Person.setCountry("中国");
Person per = new Person("zhangsan", 20);
per.getPersonInfo();
//实例化对象的方式来调用静态方法
per.setCountry("China");
per.getPersonInfo();
}
}
运行结果如下所示:
由static修饰的还有代码块,称为 静态代码块, 这些我们在后面的总结会写到。