this,static关键字
一.this关键字
我们之前使用this关键字调用本类的属性,那么除此之外this还有其他用法。 假如有一个类中有多个构造方法,要求每个构造方法都能完成某一项功能,但是这些功能都是一样的。于是就出现了重复的代码。
例子:
class Person{
int age;
String name;
String school;
public Person(){
System.out.println("我是一个构造方法");
}
public Person(int age){
this.age=age;
System.out.println("我是一个构造方法");
}
public Person(int age,String name){
this.age=age;
this.name=name;
System.out.println("我是一个构造方法");
}
public Person(int age,String name,String school){
this.age=age;
this.name=name;
this.school=school;
System.out.println("我是一个构造方法");
}
public String getInfo(){
return "名字是:"+this.name+", 年龄是:"+this.age+", 学校是:"+this.school;
}
}
public class Demo{
public static void main(String[] args){
System.out.println(new Person(12,"航三","南京大学").getInfo());
}
}
上面的代码四个构造方法都完成了一个共同的功能(输出一句话),假如这项功能需要三百行代码完成,那么就会出现大量的重复代码,于是我们使用this()的形式来实现构造方法之间的互相调用,就可以解决重复的代码
范例:使用this()实现构造方法之间的调用
class Person{
int age;
String name;
String school;
public Person(){
System.out.println("我是一个构造方法");
}
public Person(int age){
this();//调用了无参数的构造方法
this.age=age;
}
public Person(int age,String name){
this(age);//调用的是单参数的构造方法
this.name=name;
}
public Person(int age,String name,String school){
this(age,name);//调用两个参数的构造方法
this.school=school;
}
public String getInfo(){
return "名字是:"+this.name+", 年龄是:"+this.age+", 学校是:"+this.school;
}
}
public class Demo{
public static void main(String[] args){
System.out.println(new Person(12,"航三").getInfo());
}
}
上面可以使用this()的方式实现构造方法之间的调用,那么在使用this()的时候需要注意哪些问题?需要注意如下两点:
· this()必须放到构造方法中的第一行
· this()实现构造方法调用的时候不能出现递归调用
范例:错误的代码1
class Person{
int age;
String name;
String school;
public Person(){
System.out.println("我是一个构造方法");
}
public Person(int age){
this();//调用了无参数的构造方法
this.age=age;
}
public Person(int age,String name){
this.name=name;
//------------------------错误的地方---------------------
this(age);//调用的是单参数的构造方法
}
public Person(int age,String name,String school){
this(age,name);//调用两个参数的构造方法
this.school=school;
}
public String getInfo(){
return "名字是:"+this.name+", 年龄是:"+this.age+", 学校是:"+this.school;
}
}
public class Demo{
public static void main(String[] args){
System.out.println(new Person(12,"航三").getInfo());
}
}
以上代码会出现“Demo.java:14: 错误: 对this的调用必须是构造器中的第一个语句
this(age);//调用的是单参数的构造方法” 的错误。
范例:错误的代码2
class Person{
int age;
String name;
String school;
public Person(){
//--------------------------错误的地方---------------------------
this(); //这行不要
System.out.println("我是一个构造方法");
}
public Person(int age){
this();//调用了无参数的构造方法
this.age=age;
}
public Person(int age,String name){
this(age);//调用的是单参数的构造方法
this.name=name;
}
public Person(int age,String name,String school){
this(age,name);//调用两个参数的构造方法
this.school=school;
}
public String getInfo(){
return "名字是:"+this.name+", 年龄是:"+this.age+", 学校是:"+this.school;
}
}
public class Demo{
public static void main(String[] args){
System.out.println(new Person(12,"航三").getInfo());
}
}
上面代码证明了在使用this()实现构造之间的调用的时候不能出现递归的现象。
this关键字表示当前对象
当前对象就是内存中正在运行的对象,那么this在这里保存的是当前对象的地址引用。
范例:this保存当前对象在堆内存中的地址引用
class Person{
public void getInfo(){
System.out.println(this);
}
}
public class Demo{
public static void main(String[] args){
Person per1=new Person();
System.out.println(per1);//输出的内容是对象的地址引用
per1.getInfo();//输出的this保存的内容
}
}
以上代码两个输出语句的内容一致,说明了: this保存的就是当前对象地址的引用。
二、 static关键字
static 修饰的属性叫做静态属性(类变量),static 修饰的方法叫做静态方法(类方法)
当信息相同的时候,会造成资源的浪费,可将重复的信息声明为静态属性(static修饰的属性)。
范例:将重复的信息声明为static属性
class Person{
int age;
String name;
static String school;
public Person(){
System.out.println("我是一个构造方法");
}
public Person(int age){
this();//调用了无参数的构造方法
this.age=age;
}
public Person(int age,String name){
this(age);//调用的是单参数的构造方法
this.name=name;
}
public Person(int age,String name,String school){
this(age,name);//调用两个参数的构造方法
this.school=school;
}
public String getInfo(){
return "名字是:"+this.name+", 年龄是:"+this.age+", 学校是:"+this.school;
}
}
public class Demo{
public static void main(String[] args){
System.out.println(new Person(12,"航三","南京大学").getInfo());
System.out.println(new Person(18,"李四","南京大学").getInfo());
System.out.println(new Person(35,"王五","南京大学").getInfo());
}
}
静态属性有哪些要注意的地方呢?
·静态属性不依赖于对象的存在而存在,可以使用“类名.静态属性名”的方式访问。所以有人称静态属性叫做类变量。
范例:静态属性可以使用“类名.属性名”访问
class Person{
int age;
String name;
//-------------------静态变量的声明---------------------
static String school;
public Person(){
System.out.println("我是一个构造方法");
}
public Person(int age){
this();//调用了无参数的构造方法
this.age=age;
}
public Person(int age,String name){
this(age);//调用的是单参数的构造方法
this.name=name;
}
public Person(int age,String name,String school){
this(age,name);//调用两个参数的构造方法
this.school=school;
}
public String getInfo(){
return "名字是:"+this.name+", 年龄是:"+this.age+", 学校是:"+this.school;
}
}
public class Demo{
public static void main(String[] args){
System.out.println(Person.school); //----------静态调用。-------------
System.out.println(Person.name);
}
}
!!一个地方修改了静态属性,那么对其他对象也有影响
例子:
class Person{
int age;
String name;
static String school;
public Person(){
System.out.println("我是一个构造方法");
}
public Person(int age){
this();//调用了无参数的构造方法
this.age=age;
}
public Person(int age,String name){
this(age);//调用的是单参数的构造方法
this.name=name;
}
public Person(int age,String name,String school){
this(age,name);//调用两个参数的构造方法
this.school=school;
}
public String getInfo(){
return "名字是:"+this.name+", 年龄是:"+this.age+", 学校是:"+this.school;
}
}
public class Demo{
public static void main(String[] args){
Person per1=new Person();
per1.school="北京大学";
System.out.println(per1.getInfo());
Person per2=new Person();
System.out.println(per2.getInfo());
}
}
三、静态方法
静态方法:就是使用static 关键字修饰的方法。
例子:
class Person{
int age;
String name;
static String school;
public Person(){}
public Person(int age,String name,String school){
this.age=age;
this.name=name;
this.school=school;
}
public String getInfo(int age){
return "名字是:"+this.name+", 年龄是:"+this.age+", 学校是:"+this.school;
}
public static void say(){ //静态方法
System.out.println("这是一个静态方法");
}
}
public class stringtest{
public static void main(String[] args){
//-----------------------静态方法调用-------------------
Person.say();//没有实例化对象依然可以调用
// Person.getInfo();//这是一个普通方法 ---------这样写会报错----------
Person per = new Person();
per.getInfo(1);//这是一个普通方法
}
}
** 静态方法不依赖于实例化对象的存在而存在,可以使用“类名.静态方法名”访问
例子:
class Person{
int age;
String name;
static String school;
public Person(){}
public Person(int age,String name,String school){
this.age=age;
this.name=name;
this.school=school;
}
public String getInfo(int age){
return "名字是:"+this.name+", 年龄是:"+this.age+", 学校是:"+this.school;
}
public static void say(){ //静态方法
System.out.println("这是一个静态方法");
//------------------------------- 错误的地方 -------------------------------------
System.out.println("名字是:"+name);//在静态方法中访问普通属性
}
}
以上的代码出现了“Demo.java:17: 错误: 无法从静态上下文中引用非静态 变量 name”的错误
**·静态方法中不能访问普通属性
例子:
class Person{
int age;
String name;
static String school;
public Person(){}
public Person(int age,String name,String school){
this.age=age;
this.name=name;
this.school=school;
}
public String getInfo(int age){ //普通方法
return "名字是:"+this.name+", 年龄是:"+this.age+", 学校是:"+this.school;
}
public static void say(){ //静态方法
//------------------------------错误的地方------------------------------------
getInfo();//在静态方法中调用普通方法
}
}
public class Demo{
public static void main(String[] args){
Person.say();//没有实例化对象依然可以调用
}
}
以上代码出现了“Demo.java:16: 错误: 无法将类 Person中的方法 getInfo应用到给定类型;”的错误
**·静态方法中不能发出对普通方法的调用
例子:
class Person{
int age;
String name;
static String school;
public Person(){}
public Person(int age,String name,String school){
this.age=age;
this.name=name;
this.school=school;
}
public String getInfo(int age){ //普通方法
return "名字是:"+this.name+", 年龄是:"+this.age+", 学校是:"+this.school;
}
public static void say(){ //静态方法
//--------------------------------错误的地方-----------------------------------
System.out.println(this.school);//在静态方法中不能使用this关键字
}
}
以上的代码出现了“Demo.java:15: 错误: 无法从静态上下文中引用非静态 变量 this
System.out.println(this.school);”的错误,
**·证明了静态方法中不能使用this关键字
总结 :
说明静态属性(static修饰)和普通属性的区别
·静态属性不依赖于对象而存在,可以使用“类名.属性名”的方式访问,除此之外还可以使用“对象名.属性名”访问。而普通方法依赖于对象的存在,只能使用“对象名.属性名”的方式访问。
·静态属性保存在全局数据区,是在编译期进行了内存的分配,而普通属性是在运行期进行内存的分配,而且在堆内存中分配空间。
·静态属性可以在静态方法中访问,而普通属性不能在静态方法中访问。
静态方法中不能使用this关键字
静态方法中不能发出对普通方法的调用
静态方法中不能访问普通属性