类与对象的小结

类和对象的初始化问题

初始值

public/private 数据类型 变量名=初始值

 

初始化块

{
初始化内容
}
/*
非静态初始化块:
作用:给对象进行初始化。对象一建立就运行,且优先于构造函数的运行。
与构造函数的区别:非静态初始化块给所有对象进行统一初始化,构造函数只给对应对象初始化。
应用:将所有构造函数共性的东西定义在构造代码块中。
*/

静态初始化块

static{
  初始化内容  
}
/*
静态初始化块:
作用:给类进行初始化。随着类的加载而执行,且只执行一次
与构造代码块的区别:
1)构造代码块用于初始化对象,每创建一个对象就会被执行一次;静态代码块用于初始化类,随着类的加载而执行,不管创建几个对象,都只执行一次。
2)静态代码块优先于构造代码块的执行
3)都定义在类中,一个带static关键字,一个不带static
*/

构造函数

 

类名(形参){
        初始化
}

 

以上几种初始化比较,首先静态初始化块和字段的默认初始值在创建类的时候就执行了,因此只执行一次,在创建对象过程中不再执行,构造函数和初始化块是在创建对象的时候执行的,并且构造块比构造函数先执行,如果同时有静态初始化块和初始值,就看它们的出现的顺序

初始化块都是自动调用的

所以静态初始化块=静态初始值>初始化块>构造函数,如果有子类,则父类的初始化会先执行

如何在静态方法中访问类的实例成员

可以在该方法中定义本类的对象去通过对象调用类中的实例成员

关于为什么能在本类的方法中定义本类的对象

首先在本类中创建直接的对象有两种情况,一种是是在代码层面调用了自身(这种会陷入无限递归循环),还有一种是在编译层面调用自身

java的执行过程是:当程序载入时,读取了该java文件,将静态方法读到到了内存中的静态方法保存区域,将class读到了类的区域,注意:这时候的class并没有创建实例对象,内存中只是有了创建class的机器了。接下来main方法作为程序的入口方法被执行(这是只有方法没有实例对象),方法中调用了class的机器生产了一个A对象,再将A对象装载到内存中。说明编译层面其实并没有创建对象,只是告诉程序这里需要有一个对象,所以没有陷入递归。

例如

class A{
      public A a=new A()
     /*或者
    { A a=new A()}*/
}    
class text{
    main(){
    A aa=new A()
}
}
//这样在创建对像aa时会创建对象aa中a,创建对象a时又会创建对象a中的a这样就会无限递归循环下去   
class A{
      public static A a=new A()
     /*或者
    static { A a=new A()}*/
    public void name(){A a=new A();}
}    
class text{
    main(){
    A aa=new A()//因为静态变量是储存在类中的,因此所有对象共享的
    aa.show();//只调用一次方法,在方法中创建一次对象,如果方法里面有a.show()则也会陷入无限递归            
}
}

 Integer的特性

- IntegerCache
JSL规定IntegerCache为Integer类的缓存类,默认缓存了-128~127的Integer 值,如遇到[-128,127]范围的值需要转换为Integer时会直接从IntegerCache中获取。同时,我们可以通过设置java.lang.Integer.IntegerCache.high来设置缓存最大值
-Djava.lang.Integer.IntegerCache.high=255

Integer的边界问题
通过引入补码,计算机的加减运算简化为了简单的相加,数值在计算机内存中也以补码的形式存储。
原码 => 补码: 取反加一(符号位不参加运算)
补码=> 原码: 取反加一(一般情况下,符号位不参加运算)
在补码中,1000不再表示负零,而是-8。所以给定n位存储长度,可以表达数值范围为-2的n次方到2的(n-1)次方。

在计算机数值计算时,需要考虑数值精度是否一致和是否有溢出。

  1. 数值超过数据类型支持最大精度溢出后,计算结果出错(不仅仅是丢失进度)
  2. 数值计算,结果精度就最大的精度
  3. Integer计算需要考虑是否有缓存
posted @ 2022-10-01 20:17  突破铁皮  阅读(24)  评论(0编辑  收藏  举报