《Java深入解析-透析Java本质的36个话题》笔记_第五章

## 第5 章 类与接口220

### 话题30 相辅相成——基本数据类型与包装类220

(1)自动装箱拆箱

Java的一些类库(集合类)不支持基本数据类型,在1.5之前需要手动将基本数据类型转包装类型。取出数据还要调用包装类的xValue方法。

list.add(new Integer(value));

Integer i = list.get(index);

i.intValue();

 

1.5之后增加自动装箱拆箱,不需要显式转换

list.add(2);

int i = list.get(index);

 

注意有些情况不能把基本数据类型当包装类使用

如:

int i = 10;

Integer integer = i.valueOf(2);//报错

 

Short s1 = 1;

Short s2 = 2;

s1 +=s2; // 报错,相当于s1 = (Short)(s1 + s2);

 

(2)包装类的缓存

包装类也是不可变的,跟String类相似。

包装类实现了缓存,基本数据类型转包装类型,如果基本数据类型存在包装类型的缓存范围内,则返回该缓存对象。

(3)Interger类特殊性

Interger类可以设置系统属性修改缓存上限。

“==” 或“!=” 运算符,如果一个操作数是基本数据类型,另一个操作数是包装类型,包装类型会转成基本数据类型再比较值。

 

### 话题31 分门别类——数组的阐述232

(1)数组声明

int[] i1;

int i2[];

 

(2)多维数组

Java中多维数组不是真正的多维,采用的是数组的数组实现的

区别C/C++,Java中的多维数组可以不是矩阵数组。

int [][] a = new int[2][];

a[0] = new int[4];

a[1] = new int[5];

 

a[0] 跟 a[1] 元素个数不一样。

(3)数组clone

数组的clone方法为浅复制,仅保证复制后数组的地址不一样,元素没有复制。

 

如果数组的对象是引用类型,有可能修改了数组的某个元素内部数据会导致别的地方使用的错误。

多维数组(维数在2~255之间)经过复制,只有最高维指向的对象不同,其它低维度的是相同的。

String[][][] a = new String[1][1][1];

a[0][0][0] = ""Java;

String[][][] b = a.clone;

 

a == b:false

a[0] == b[0] :true;

a[0][0] == b[0][0] :true;

a[0][0][0] == b[0][0][0] :true;

 

(4)数组输出

char类型的数组print输出的格式跟其他类型的不一样,将数组中所有字符依次输出。其它类型数组输出都是toString返回的结果。

 

### 话题32 规矩方圆——定义规范的接口类型242

(1)如果定义的接口为空(没有任何成员),还是存在9个方法成员,来自于Object中声明的9个public方法

接口中所有变量都是public static final ,所有方法都是public abstract,所有内部类和内部接口都是public static

(2)接口是不能实例化的,使用new创建的实例是实现了接口的匿名内部类

(3)接口允许多继承,继承规则跟类的相似

 

两个接口有相同名称变量x,当同时实现两个接口,调用x必须使用限定名称,否则会发生编译错误。

两个接口有相同名称方法,如果重载了,要全部实现,如果不是,只需实现一个。参数要是两个重名方法参数的子签名(List是List<String>和List<Object>的子签名),返回类型是两个重名方法返回类型的可替换类型。

interface Dog{

    String kind = "Dog";

    void run(List<String> list);

    Colection<String> jump();

}

interface Cat{

    String kind = "Cat";

    void run(List<Object> list);

    List jump();

}

class Animal implements Dog,Cat{

    String s1 = Dog.kind ;

    String s2 = Cat.kind ;

    @Override

    public void run(List list){}

    @Override

    public List jump(){}

}

 

### 话题33 彻里至外——嵌套类型248

(1)静态成员类

static 修饰的类,不需依赖外围类

(2)内部类(非静态嵌套类)

内部类需要持有外围类的引用才能创建,创建内部类对象时,系统会将外围类对象作为参数传入内部类的构造器中

内部类不能声明静态成员或静态初始化块,定义final修饰的值是编译期常量的静态变量是可以的。

继承内部类,在构造方法中需要绑定一个外围类对象

 

```java

// 继承内部类,在构造方法中需要绑定一个外围类对象

public class InnerClassTest extends Outer.Inner {

 // 注释了这段会报错

 public InnerClassTest(Outer outer) {

  outer.super();

 }

}

 

class Outer {

 // 创建内部类对象时,系统会将外围类对象作为参数传入内部类的构造器中进行绑定

 class Inner {}

}

 

/**

 * 子类继承父类

 * 子类内部类继承父类内部类

 */

class InnerClassTest2 extends Outer {

 class Inner extends Outer.Inner {}

 

 public void go() {

  InnerClassTest2 innerClassTest2 = new InnerClassTest2();

  // Inner 持有InnerClassTest2对象引用,Inner是Outer.Inner子类,Inner初

  // 始化的时候调用Outer.Inner的构造方法,Outer.Inner需要跟外围类Outer对象绑定,

  // InnerClassTest2对象也是Outer 的子类,跟Outer.Inner绑定是可以的

  InnerClassTest2.Inner inner = innerClassTest2.new Inner();

 }

}

```

(3)本地内部类

在方法,构造器,初始化块中声明的类

不能使用访问修饰符和static修饰

本地内部类可以访问其声明的方法,构造器,初始化块所属类的左右成员,如果是在静态方法或静态初始化块中声明,需要通过对象引用才能访问实例成员。

本地类只能访问final修饰的局部变量或参数

public class LocalClass{

    LocalClass(){

        int x = 2;

        final int y = 3;

        class local01{

            // int z = x;//报错

            int w = y;

        }

    }

}

 

(4)匿名内部类

跟本地内部类类似,只能访问final局部变量和方法(构造器)的参数

匿名类会隐式继承某个类或实现某个接口,所以不能继承和实现接口(尽管接口可以多继承)

 

(5)嵌套接口

在类中或接口中声明的接口,嵌套接口是静态的

类实现接口,并不需要实现接口里面的嵌套接口

 

### 话题34 不胜枚举——枚举的神秘258

C/C++ 的枚举类型是int类型常量值,不安全。

1.5 加入枚举

枚举是类,枚举常量是类的对象,在枚举类外无法创建枚举对象

枚举类实例初始化中不能访问静态变量(枚举类特殊初始化方式:构造器先于静态初始化),但值是编译时常量的静态变量可以

 

### 话题35 按部就班——加载、链接与初始化265

(1)虚拟机启动后,会创建一个启动类加载器,启动类加载器会加载扩展类加载器和系统类加载器。

(2)双亲委派

调用ClassLoader类的loadClass方法加载一个类或接口,类或接口在加载后不会初始化。

Java库中的类是由启动类加载器加载的,自定义的类通常由系统类加载器加载的。

(3)深入初始化

如果构造器没有调用本类的其它构造器,可看做所有的实例变量声明处初始化和实例初始化块都会复制到所有构造函数执行语句的最前面。如果调用本类其它构造器,这种复制在其它构造器中执行,调用this的构造器不执行这种复制。所有的静态变量声明处初始化可看做复制到静态初始化块中。

```java

private int x;

private int y = 20;

private static int xStatic;

private static int yStatic = 20;

 

{

 x=20;

 if(y>20) {

  throw new Exception();

 }

 //return 不能使用

}

 

static {

 xStatic = 30;

 if(yStatic>20) {}

 //return 不能使用

}

 

public InitQuestion() throws Exception{

 this(0,0);

}

 

public InitQuestion(int x) throws Exception{}

 

public InitQuestion(int x,int y) throws Exception{}

// 可以看做下面的

private int x;

private int y;

private static int xStatic;

private static int yStatic;

 

static {

 yStatic = 20;

 xStatic = 30;

 if(yStatic<=20) {}

}

 

public InitQuestion() throws Exception{

 this(0,0);

}

 

public InitQuestion(int x) throws Exception{

 y= 20;

 x=20;

 if(y>20) {

  throw new Exception();

 }

}

 

public InitQuestion(int x,int y) throws Exception{

 y= 20;

 x=20;

 if(y>20) {

  throw new Exception();

 }

}

```

 

实例初始化块和静态初始化块不能使用return。

静态初始化块不能抛出任何受检异常。

实例初始化块能抛出任何受检异常,前提是类中所有构造器必须同时抛出相应的异常或异常的父类。

 

<init> 与 <clinit>

编译器为每一个构造函数创建<init>方法。这些构造函数集合了实例变量声明处初始化和实例初始化块。

也为所有静态初始化语句集中到一起,生成 <clinit>方法,如果没有静态语句就不生成。

 

(4)类初始化

(5)接口初始化

(6)主动使用与被动使用

主动使用:访问的成员是类(接口)中声明的成员。

被动使用:访问的成员是父类继承的。

被动使用时不会初始化被动使用关联的类(接口)

 

### 话题36 择优录取——类型及其成员的选择283

遮蔽:在某作用域中,相同名字的类型或类型成员,其中一个遮蔽另外一个。

例如:在构造函数的参数value作用域内遮蔽了相同名字的成员变量value。

class A{

private int value;

public A(int value){

this.value = value;

}

}

(1)类型选择

(2)变量选择

 

(3)方法选择

(4)模糊

当名称可能解析为变量名,类型名或包名时,变量名优先于类型名,类型名优先于包名。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
目录 目 录 第1章 基本概念 1 话题1 开门见山——测试你的Java水平 1 话题2 世外隐者——隐居深山的“关键字” 2 话题3 疑团满腹——标识符更深层的思考 6 话题4 鞭长莫及——我的特殊字符,你不能用! 10 话题5 移星换斗——从byte b = 1谈类型转换的神秘 16 话题6 扑朔迷离——浮点类型的种种悬疑 22 话题7 水落石出——浮点结构的最终解密 31 话题8 龙虎争霸——基本for循环与加强型for 循环的对比 45 第2章 运算符与表达式 52 话题9 莫衷一是——i+++j该如何计算? 52 话题10 千差万别——++i与i++仅是“先加”与“后加”的差别吗? 56 话题11 强大相径庭——相除与求余在Java中的具体表现 61 话题12 移形换位——移位运算的真实剖析 75 话题13 鞭辟近里——条件运算符(?:)的类型深入 81 话题14 井然有序——运算顺序的详细挖掘 86 话题15 异曲同工——交换变量的3种方式 90 话题16 择木而栖——开关选择表达式switch的类型内幕 95 第3章 String类 103 话题17 来龙去脉——“+”是怎样连接字符串的? 103 话题18 一成不变——不可修改的String对象 107 话题19 钩深索隐——String字符最大长度的探索 111 话题20 追本溯源——追寻String字面常量的“极限” 116 话题21 旧调重弹——再论equals方法与“==”的 区别 122 话题22 顺藤摸瓜——从字面常量到String常量池 136 第4章 方法、构造器与变量 143 话题23 相差无几——main方法很“特殊”吗? 143 话题24 一词多义——方法重载的详细说明 150 话题25 踵事增华——方法重写的真正条件 166 话题26 一叶障目——方法与成员变量的隐藏 177 话题27 发轫之始——执行初始化的构造器 182 话题28 殊途同归——成员变量不同的初始化方式 193 话题29 按部就班——初始化顺序与向前引用 206 第5章 类与接口 220 话题30 相辅相成——基本数据类型与包装类 220 话题31 分门别类——数组的阐述 232 话题32 规矩方圆——定义规范的接口类型 242 话题33 彻里至外——嵌套类型 248 话题34 不胜枚举——枚举的神秘 258 话题35 按部就班——加载、链接与初始化 265 话题36 择优录取——类型及其成员的选择 283 内容简介 本书分为5章,分别为“基本概念”,“运算符与表达式”,“String类”,“方法,构造器与变量”,“类与接口”。 通过以上方面介绍那些常见、常用却少为人知的Java知识。虽然内容相对基本,但都不是容易解答的。目前更多的开发人员(不乏多年开发经验者),也仅仅停留在Java表面的层次,而本书,将更深入一层地去讨论Java话题,令读者耳目一新,知其然,更知其所以然。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁星点点-

请我喝杯咖啡呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值