java学习过程出现第一次滞后,背景:清明节以及持续1周的雨。
- 方法签名=方法名+参数列表。
- 在覆盖方法时需要注意:1.覆盖后的方法返回类型的兼容性;2.新的方法的可见性必须不低于原方法的可见性。
- 这里有一个因果:每次调用方法都要进行搜索开销很大,所以 虚拟机 会预先为 每一个类 建立方法表,使用时直接查表,此外,除了private,static,final方法,所有的方法都是动态链接。
- 调用 某个方法 的实际解析过程 详述于白皮书P160;
- final 修饰的类将不允许出现继承,此类中所有的方法都相当于被final修饰,但数据域并不没有被final修饰。final 修饰的方法将不允许被覆盖。final 修饰的数据域 相当于const只能被初始化赋值,不能改变。
- final 修饰的类或方法的目的:防止目标在子类中改变语义
- java中内联产生条件:代码简单、调用频繁、不会被覆盖的方法。
- 对于类的类型转换说明事项:a.只能在 继承层次 中进行。b.子类可以强制转换为超类。c.在超类强制转换为子类时,应该是失败。为代码严谨,在类对象进行类型转换前应该测试,加上测试 if(需要转换的变量名 instanceof 需要转换成的类型名) {转换成功do}
- abstract关键字——抽象类,方法。
- 抽象类不能存在实例,但可以存在引用,并且这个引用应该引用抽象类的子类实例,因为抽象类本身不能存在实例。抽象方法只能声明,不能加上{}进行定义,并且需要被abstract修饰。详述于白皮书P164.
- 类即使不含有抽象方法,也可以使用abstract,将其定义为抽象类;如果子类中依然存在未定义的抽象方法,那么这个子类需要使用abstract修饰,因此也不能存在实例,这里与C++不同,在C++中,只要存在纯虚函数,这个类就自动变为抽象类
- java中的protect修饰关键字,其修饰的内容对两者可见 a.子类 b.同包中的类,作者曾经提到不推荐使用protect,但确实存在某种情况使用protect更好一些。
- Object 类是java种所有类的子类,其中需要注意java的数组无论是基本类型还是对象数组,应该视作为某个类,所以它们也是Object的子类。
- 这里有一个因果:因为13,所以,Object类型的变量可以引用任何类的对象实例,这里需要注意,在引用后的使用过程中很有可能使用(强制类型转换)来使用原本类的某些方法。这里有一个补充说明:java中,只有基本类型不属于类对象。这里有一个与C++的对比:C++中不存在根类(类似JAVA中的Object),但存在一种指针(void*),任何类型的指针都可以强制转换为此类指针。
- Object 类中的equals方法,只是检测两个对象是否引用的同一实例而已,并没有进行真正意义上的根据数据域进行对比得出结论。这里有一个改进:虽然a.equals(b)可能实现a与b的引用地址的比较,但是二者可能有null的存在,所以使用静态方法Objects.equals(a,b)可以预防这种现象,该方法返回值:当a=b=null时为true;a,b有一个是null时为false,否则调用a.equals(b)并返回相应结构。
- 在子类中(如果需要的话)对超类equals进行覆盖时,需要先用超类的equals方法进行检测,然后再对比子类中的特有数据域。详述与白皮书P170,对于equals方法的重定义规范,详述于P179~P173;
- 对于数组的处理总是特殊的,其中数组equals方法更应该利用Arrays.equals静态方法
- 这里有一个小技巧:在覆盖超类方法的前头加上@Override 可以用于检测 覆盖失败而是添加了一个无关方法(这种情况的产生是由于 参数列表错误)。
- 每个类对象都有一个散列码(所以数组也有),使用hashcode()方法或者hash方法或者自定义的方法得到。其中String类的散列码的计算与其内容有关,所以内容相同的String对象导出的散列码相同,StringBuffer类 并没有覆盖hashcode方法,所以使用的是Object方法,所以得到的是地址信息。这里有一个注意:如果覆盖额equals方法,就必须同时覆盖掉hashcode方法,这里可以看出调用hashcode方法是需要 (对象名).hashcode(),这样做是为了用户可以将对象插入散列表。所以这里还有一个注意,equals中利用到的判断是否相等的数据域,新hashcode方法需要同样使用它们作为参数用于计算,对于基本类型参数无法调用.hashcode,可以通过装箱调用,也可以使用Object静态方法hash()计算,详述于白皮书p175。数组对象Arrays.hashcod()方法。
- 可以使用getClass().getName()得到对象的类型名,每个Object类都有一个toString方法,用于显示数据域,达到辅助测试的效果,可以有两种方式调用,a.x.toString(),直接通过对象变量名调用,b.“”+x,自动调用x.toString,然后与“"相连接,此外,.println(x)中,将自动调用x的toString方法。对于数组对象,使用静态方法Arrays.toString,作者建议为每一个自定义类添加toString方法,用于反应状态域信息。对于多维数组,使用Arrays.deepToString()静态方法
- 使用getSuperClass方法可以得到超类信息。
- 泛型数组列表:在添加删除数组元素时有自动调节数组长度的功能,其中设计到菱形语法。详述于P181,白皮书。ArrayList<类型名> 变量名 = new ArrayList<可添入类型名>();变量名.add()添加元素,变量名.size()返回数组列表容量,变量名.ensureCapacity(数量),以及一些具体使用方法详述于P181,白皮书。这里需要注意一点,所涉及的索引i是包括0在内的,所以使用时需要将索引与真实数组索引等同。,toArray方法可以将数组列表中的内容导出到数组中。
- 对象包装器与自动装箱 P187白皮书,以及可以修改数值参数的方法是通过holder类型变量,例如IntHolder类型。
- 类型化数组列表与原始数组列表之间的兼容问题,详述于P186,白皮书。
- 变参方法,详述于P190,实际上,printf接收两个参数,1个是格式字符串,另一个是Object[]数组,如果在Object[]数组中存在基本类型,那么将会自动装箱。最后一个参数是数组的方法,可以被重定义为变参方法,但不需要破坏现有代码。
- 枚举类型/类 ,详述于P191,可以使用==判断两个枚举类型变量是否相同,因为这两个都是引用枚举类型常量的地址,没有创建新的实例,所以可以通过地址来判断是否相同。
- .常量名.toString得到常量名,变量=Enum.valueOf(枚举类型名.class,枚举常量名),设置变量为特定枚举常量,每一个枚举类型都包含values方法,该方法返回该类中的所有枚举常量,注意用枚举类型的数组接收,ordinal是枚举类型常量的方法,返回该常量的值(位置,从0开始)。
时间: 2024-10-20 15:33:12