单例模式,静态代码块,接口你都懂了吗

过了这莫多天,我又学习了不少东西,今天我们就再来看看、、、、
*

单例模式

模式:由专家总结出来的在某肿情况下解决某舞问题的最佳解决方库,是思想,是知规, 是种曲象的
内容
意图:保证一个费仅有一一个实例, 井提供一个访问它的全局访问点。
主要解决:一个全国使用的类频蒙地创建与销股。
何时使用:当您想控制实例数目,节系统瓷源的时候。
单例模式有多种写法,最常见的是做汉模式和饿汉模式

俄汉单例模式

优点:没有加锁,执行效率会揭高
缺点:类加联时就初始化,渙费内存
面内对像着程胆
壤程实现:
。私有构造器
。静志的私有属性
公共的静态方法

懒汉单例模式

懒汉式:主要是针对最汉式中不管是否需要使用对象都先点建对象子起的内存浪费
优点:由于采用延迟处理的方式,所以比较性约内存
缺点:在多线程不能正常工作
静态static关键字
用于修饰成员
。随着类加收。随着类消失
优先于对象。用类名直接访问

静态属性

statc属性是当前类的所有对象所共有的共同属性只有一个,而普通属性各个对象都有自己的,相互隔
圓),任何-一个当前类对象修改这个属性,所有其他类对象的这个属性都会受影响:绕计A1类的构建次数
执行顺序
静态属性–属性-构造器
访间的方式
可以使用类名静态属性名”城者”对象名静态属性名”的方式进行动问。[范围限制]

定义常量

命名规则:名称全大写,下划线分司
。声明语法: public statkc final double MN. NUMBER=0.1: .
, 声明的同时直接进行初始化
先声明后在static静态块中赋值

静态方法

, 因为可以值接使用类名方法名"的形式直接调用静态方法,静态方法执行时很有可能并没有构建对
象。所以在静态方法中不允许使用his/super之类用于指定对象的关键字
当然在静志方法中允许创建对象,并调用对像方法
静志方法只能直接访问静态成员,不能陕访问静态成员

静态块

.类在执行时需要通过一一个作类加载器的电性榕程序加收到内存中。类在运行时般不会发生变
化。所以类不会随能加就,在整个运行过程中只加就一次,而且常生内存
●静志块在类加概完毕后自动执行,而且只执行-次
非静志块
非静态块在类内且在所有的方法之外。非静态块并不会在类加载后自动执行,而是在构建当前对象时自
动执行。new- -次则会执行一 次执行时机在构造器之前执行
●当类加就完毕会自动优先处理出atc属性和tald块, 这两个优先级是相同的,所以进在的先处理维
。new对象时,处理非静态属性和非静态块,这两个优先级是相同的,所以课在前先处理谁
,最后执行构道器
使用注意事项
●静当方法只模动问静态成员,静态有访问局限性
●静志方法中不能有this super关键字
●主函数是静志的
什么时慢使用静态
。当成员交量的鼓据各个对象都相同时,可以用tatic慷饰的,让多个对像共享
,方法如果访同了特有数据非静态成员变量) .该图数是丰静志的。方法如果没有访问特有数据,
那么该方法就星静态修饰
。 如果类中的功能都是静态的,那么波类创疆对象是没有意义的,所以构造方法需要私有化
方法中的可变长个数的参数
语法:数据类型.变量名。- 必须作为最后-个参数出现
具体处理过程中实际上星按照数组的方式进行处理,而且数组不会为null

pu1ic woid ppcint... k1)[
if(k1.1ength>0){
forcint 1=0;1<k1. length:1++)
syster. out. print1n(I[]);

woid plpiece. am可变长参数可以是Cbjectol数组
注意:一个方法的最后一个位置只有一 一个,所以方法中的可变个数的参数只能有一个
statid相关问题
父类中定文的静志方法类方法)是否可以通过“子类名静志方法名”的方式进行调用?
可以,因为地承的特性

public Class Test1public static vold nain(string[l args) {
son. PPO:
class Fa[
public atatic wid PpO{
Systen. out .rintn("Fa. p0");
 class son extends FaO}

父类中定文的静态方法(类方法)是否可以在子类中进行覆盖定义(马) ?
可以,旧星方法签名必须一-致.方法必须为statk定义

public class Test1
public static woid main(string[] args) {
son. pPO:
5
class Fal
public static vold ppO{
Systen. out .printn("Fa.ppO0*);
}} class son extends al
public static woid pO{
systen. Qut orintmnc"on,ppO"D:)
特殊点:静态方法也允许通过对象进行调用
public class Test1public static woid main(string[] args) 《
阳ff-pem
f.pO; //注意这里调用的是父类中定 义的静去方法。不是子类中覆益出义的新方法
class at
public static woid ppO{
systen. out rintnc"appO"):
}
)
class son extends Fal
public static woid ppOl
Systen. out .rintn"on.ppOD:
}
)

静态快没有覆盖定义的概含。如果父子类中相定义了静志块,-定是先执行父类中的静态块。然后运行
子类中的静态块
。加载顺序为先父后–先执行父要中定义的静态属性和静态块
中然后执行初始化操作-先处理父类中的成员属性和非静态块。再执行父类构造器:后执行子类的定
义内容
静态导入
在一个类中反复使用要某个类中的静态方法。如果使用静态导入则在当前类中不需要再写类名称
在JDK5当中提供了导入静态方法的mport博句。
●调法: importstatic jova lane Math.t:导入Math类中的所有静志方法
●注意要求使用JDK1.5+版本, 否则编译不通过

 inport static java .1ang .4ath.;
public class Test1public static woid main(string[] args)double a1 - -12.345;
systen. out .print1n(abs(a1));
Systen. out .printn(cos(al));
Syster. eut .printIn(sin(al));

成员应用细节

在这里插入图片描述
Java虚拟机包含类装载器子系统,执行引擎、运行时数据区、本地方法

接口和垃圾收集模块。

●类装载器子系统:根据给定的全限定类名(如: java.lang.Object) 来装载class文件到运行时数据
区域的方法区中。
●执行引擎:执行字节码或执行本地方法。
●运行时数据区:就是常说的VM的内存,堆,方法区,虚拟机栈,本地方法栈,程序计数器。
●本地方法接口:与本地方法库交互,作用就是为了融合不同编程语言为Java所用,它的初衷是融合
首先通过编译器把Java代码转换成字节码,类加载器再把字节码加载到内存中(运行时数据区的方法区
内) , 而字节码文件只是VM的一套指令集规范,不能直接交给底层系统去执行,所以需要特定的命令
解析器执行引擎将字节码翻译成底层系统指令,再交给CPI去执行,而这个过程需要调用其他语言的本地
库接口来实现整个程序的功能。
在这里插入图片描述

方法的代码片以及整个类的代码片断被存储到方法区内存中,在类加载的时候这些代码片段会被载入。
方法区与Java堆-样, 是各个线程共享的内存区域,它用于存储已被虚拟机加载的类型信息、常量、静
态变量、即时编译器编译后的代码缓存等数据。
●JDK 8完全废弃了永久代的概念,改用在本地内存中实现的元空间来代替,JDK 7中永久代还剩余的
内容(主要是类型信息)全部移到元空间中。异常情况:方法区无法满足新的内存分配需求时,将
抛出00M异常
●运行时常量池是方法区的一部分。 并非预置入Class文件中常量池的内容才 能进入方法区运行时常
量池,运行期间也可以将新的常量放入池中,这种特性被开发人员利用得比较多的便是String类的
intern()方法。
方法执行使用的是栈,该方法需要的内存空间在栈内存中分配,称为压栈。方法执行结束后,该方法所
占用的内存空间自动释放,称为弹栈。栈中主要存储的是方法体当中的

局部变量

引用和指针的区别:
引用也叫句柄,类似于指针,但是和指针是不同的。指针是-一个存放地址的变量,使程序员可以灵活的
访问内存,由于可以对指针进行任意的运算操作,所以给程序带来了安全隐患和意想不到的结果。引用
继承了指针节省内存的优点,但是限制了对地址的操作,它是安全的。Java中所有的变量都是一个引
用,java中没有指针的概念。

Person p=new PersonO; -- 调用的是Person类中的无参 构造器 
class Person{
private string name :
private Job[] jobs;
}

在程序执行过程中使用new运算符创建的java对象,存储在堆内存中。对象内部有实例变量,所以实例
变量存储在堆内存当中
变量分类:
局部杏量,方法体中声明
●成员变量,方法体外类内声明
。实例变量,没有static修饰符, 各个不同对象相互隔离
》静态变量,有tatic修饰符, 这个类的所有对象共享
》静态变量存储在方法区内存中
●三块主要内存中变化最频繁的是栈内存, 最先有数据的是方法区内存,垃圾回收期主要针对的是堆
内存
自动垃圾回收机制GC什么时候会将java对象的内存回收
●当堆内存中的对象称为垃圾数据的时候会被GC回收
, 什么时候堆内存对象会变成垃圾?
)引用计数法:为每个对象创建一个引用计数器,有对象引用时计数器+1,引用被释放时计数
器1,当计数器为0时就可以被回收。它有一个缺点就是不能解决循环引用的问题
。可达性算法(引用链法) :从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一
个对象到GC Roots没有任何引用链相连时,则证明此对象是可以被回收的。

总结

●栈内存存储基本类型的变量和对象的引用变量
●堆内存用于存放由new创建的对象和数组。每new-一个对象就在堆内存中开辟一 个新的存储空间存
储此实例对象
, Person p= new Person(执行new命令时程序执行两步: a:在堆内存中开辟- 段空间,存储new出
来的对象; b:在栈内存中添加-个变量p,p中存放的是该对象在堆内存中开始存放处的物理地址
,p= null;执行此步骤的时候程序只是更改栈内存中的P变量所保存的地址,把地址指向nill,而井没
有操作堆内存(把p所指向的对象实例清空回收)
●无论是形参或者实参,执行XXX = nll;操作时都是把XXX变量栈中存储的地址改为指向null的地
址。不操作堆中的数据。

public void pp(int k){
system. out .print1n(k);
5 pp(1)

具体问题

由类创建一个对象,JVM内存中发生了哪些事情?
MyClass mc = new MyCass0;以这条语句为例, MyClass mc =使虚拟机栈中生成了一个指向MyClass
对象的地址; new MyCass()则在堆中分配了对象mc成员变量的空间。
栈和堆的区别
●管理方式:栈自动释放,堆需要GC
●空间大小:栈比堆小
●碎片相关:栈产生的碎片远小于堆
●分配方式:栈支持静态和动态分配,而堆仅仅支持动态分配
●效率:栈的效率比堆高
方法的问题

方法的分类:

●无参无返(没有参数列表,没有返回值)单纯的作为功能代码的聚合使用便于功能复用
●无参有返(没有参数列表,有返回值)
●有参无返(有参数列表没有返回值)适用于功能需要根据参数来进行计算的情况,但是计算的最终
结果又无需返回处理
●有参有返(有参数列表,有返回值)适用于功能需要根据参数来进行计算的情况,而且最终的结果
需要返回处理

方法的形参和实参:

●形参:是定义在方法声明上,用于指定该方法需要传递的参数类型的
,实参:是调用方法时,实际传递的参数值
方法参数传递
●基本数据类型作为参数传值:传值传的时值的内容,来到另一个方法空间之后,这个值和之前没有
任何关系。(如你们拷贝我分享的网盘内容不会改变我原有玩盘内容)
●引用数据类型作为参数传值:传值传的时对象在堆的地址值,所以了两个内容指向了同一空间是相
互影响的。(如你登陆我的网盘拷贝内容改变的话会改变我的网盘内容)
基本数据类型的对象缓存
在不可变类Integer类定义中查看源代码可以发现一个定义

private static class Integercache {}这实际上就是Integer的cache
 Integer numl - 12;
  Integer num2 - 12;
这块相等,<=127 都是真的
System.out.print1n(num1 -- num2);

是因为在Integer中包含有一个缓存池, 缓存值为-128到127之间。

●定义Integer k1=12是先在缓存池中查找12这个对象,如果有则直接使用
●new Integer(12)-定会引发对象的创建,而不管缓存池中是否包含这个对象
Integer k1 = 12;
Integer k2 = 12
system .out. printIn(k1 == k2):;//true , k1和k2都是引用类型,所以==比较的足地址
Integer k3=new Integer(12);
system .out. print1n(k1=-k3);//false
 Integer k1 = 129;
Integer k2 = 129;
System.out. printIn(k1 == k2)://false.因为缓存只缓存-128127之间的数据
IntegerLonglShort\Byte中都有缓存池、character中也有缓存池, boolean只有true/false两个
字符串缓存池
String中包含-一个缓存池,当使用某个字符串对象时会首先在缓存池中进行查找,如果存在则直接返回
这个对象的地址;如果不存在则会在缓存池中进行创建,创建完成后返回地址
string s1=" abc";
string s2=" abc";
string s3=new string(" abc");//这里会创建2个对象,一个在缓存池中,一个是new导致的新创
建对象
system .out. print1n(s1=-s2)://true
System . out. print1n(s1--s3)://false

注意:如果通过字串拼接所得内容和某个字串内容一-致, 但是地址不同

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值