黑马程序员——Java之this和static关键字解析

时间:2022-05-11 12:23:54

——–Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

一:this关键字

this的用法:(1)在对对象的属性进行初始化时,要调用相应的构造函数,当构造函数中的参数名称与对象的属性名一样时,需要使用this关键字修饰对象的属性
* (2)this语句只能用构造函数间的相互调用,如:this();相当于空参的构造函数
* (3)this语句只能放在构造函数的第一行
*
* 二:static关键字
*
static的用法:(1)是一个修饰符,用来修饰类的成员(成员变量和成员函数)
* (2)用static关键字修饰的成员变量或成员函数,有两种调用方式a:通过对象调用 b:通过类名直接调用(原因是这些被static修饰的成员函数和成员变量是存放在共享区(方法区)中的)
* (3)特有的数据应该随着对象的存储而存储
* (4)主函数是静态的
* static的特点: (1)静态成员随着类的加载而加载,随着类的消失而消失,说明它的生命周期最长
* (2)静态成员在内存中出现优先于对象(明确静态成员先存在,对象后存在)
* (3)静态成员被所有的对象所共享
* (4)静态成员可以直接通过类名调用
* 类变量和实例变量的特点:
* (1)存放的位置不同
* a:类变量随着类的加载而加载,存在于方法区中
* b:实例变量随着对象的创建而存在于堆内存中
* (2)生命周期的不同
* a:类变量生命周期最长,随着类的消失而消失
* b:实例变量的生命周期随着对象的消失而消失
* static关键字的使用注意事项:
* (1)静态方法只能访问静态成员(静态成员变量,静态成员方法)
* 非静态方法既可以访问非静态成员也可以访问静态成员
* (2)静态方法不能出现this , super关键字
* 因为静态成员优先于对象存在,所以静态方法中不能出现this
* 静态成员有利有弊:
* (1)利处:对对象的共享数据进行单独的存储(方法区),节省内存空间,没必要在每个对象中都存储一份相同的数据
* 可以通过类名直接调用
* (2)弊端:声明周期过长;访问有局限性(只能访问静态成员)
* 什么时候使用静态:
* (1)什么时候使用static修饰成员变量?
* 当对象中出现共享数据(是指属性的值)时,把共享数据抽取出来用static修饰成类变量
* 对象中特有的数据要定义成非静态的实例变量存在于堆内存中
* (2)什么时候使用static修饰成员函数?
* 当函数内部没有访问到非静态数据时(对象特有的数据),就可以把该方法定义成类方法
* 理解静态代码块,构造代码块,构造函数的执行顺序:
* (1)静态代码块是给类进行初始的,随着类的加载而加载,只在加载时执行一次,其中同样只能访问静态成员,
* (2)构造代码块是给对象进行初始化的,也只执行一次,其执行顺序优先于构造函数,可以访问静态或非静态成员
* (3)构造函数是给对应对象进行初始化的,只有在创建对象时才会执行
* JVM在执行Person p=new Person(“zhangsan”,20);语句时,在计算机内存中都做了什么事
* (1)因为new会用到Person.class文件,所以会先去找Person.class文件并加载到内存中
* (2)执行该类中的静态代码块,如果有的话,给Person类进行初始化
* (3)在堆内存中开辟空间并分配内存地址
* (4)在堆内存中建立对象的特有属性,并进行默认初始化(共享属性存放到方法区中)
* (5)对对象的属性进行显示初始化
* (6)对对象用构造代码块进行初始化
* (7)对对象用对应的构造函数进行初始化
* (8)将该内存地址值赋给栈空间的p变量
* 类中定义的成员变量和成员方法(无论是静态的还是非静态的)都要被调用后才能使用
* 说明:(1)对于静态成员,可以直接采用类名.静态成员的方式调用
* (2)对于非静态成员,必须先创建类的对象,通过对象.成员的方式进行调用
* (3)在同一个类中,调用静态成员时,可以省略”类名.”;调用非静态成员时,可以省略”this.”
*
三:单例设计模式

设计模式:解决某一类问题最行之有效的方法,java*有23种通用的设计模式
* (1)单例设计模式(是为了让类的对象在内存中唯一存在,而不能随便通过new关键字创建)
* 思路:
* a:想要保证类的对象在内存中是唯一的,首先要先禁止在其他类中创建该类对象(即把类的构造函数私有化)
* b:要想使用该类中提供的方法和属性,又要求必须要创建对象,因此只能在本类中自定义一个对象
* c:为了其他类能够访问到这个对象,必须提供公共的访问方法(该方法返回一个类的对象)
* 程序实现:
* a:将构造函数私有化
* b:在类中创建一个本类的对象
* c:提供一个方法可以获取到该对象
* A:饿汉式

class Single{
private float height;
private Single(){};
private static Single s=new Single();//先初始化对象
public static Single getInstance(){
return s;
}
}
  • B:懒汉式(存在线程安全问题)
    class Single{
private float height;
private Single(){};
private static Single s=null;
private static Single getInstance(){
if(s==null){//双重if判断,在确保线程安全的前提下,提高代码的执行效率
synchronized(Single.class)//线程安全问题解决方法(上锁)
if(s==null){
s=new Single();
}
}
return s;
}
}