java.util.List 的 remove(int) 与 remove(Object)

最近看到 V2EX 上一个帖子《关于 Java foreach 循环删除多个元素的有趣问题(不是抛异常哦)》,我根据代码预测的执行结果与实际楼主贴出的并不相同。看了评论,才发现自己忽略了一点,觉得有点意思,因此记录一下。

July 8, 2018 · Zi WANG

译|if(a - b < 0) 与 if(a < b) 的区别

一个针对此问题 Stack Overflow 上的回答。

May 8, 2018 · Zi WANG

【Java 核心笔记】04.07. 反射

能够分析类能力的程序称为反射(reflective),其可以: 在运行中分析类 在运行中查看对象 编写泛型数组代码 调用任意方法 java.lang.Class 类用于描述 JVM 中使用的类。 在运行中分析类 java.lang.reflect中三个重要的类Field、Method、Constructor分别用于描述类的域、方法、构造器。 Class类对象的 getFields、getMethods、getConstructors方法将分别返回类提供的public 域、方法和构造器数组(包含超类的公有成员) getDeclaredFields、getDeclaredMethods、getDeclaredConstructors方法将分别返回类中声明的全部域、方法和构造器数组(但不包含超类的成员)。 在运行中分析对象 在获取Field对象后,通过其get方法,可以得到某个对象该字段的值。 直接访问私有域,get方法会抛出IllegalAccessException异常。但如果一个Java程序没有受到安全管理器的控制,就可以通过Field对象的setAccessible方法覆盖访问控制(Method、Constructor同理)。 通过get方法得到的是Object。如果字段为基本类型,会将其打包为包装类型,并以Object形式返回。 通过set方法可以修改字段的值。 编写泛型数组代码 将一个 Employee[] 临时地转换成 Object[] 数组, 然后再把它转换回来是可以的, 但最开始就是 Object[] 的数组却永远不能转换成 Employe[] 数组。(但可以进行单个元素的转换) Employee[] employees = new Employee[10]; Object[] objects = employees; System.out.println((Employee[]) objects); // 可以转换 objects = new Object[10]; System.out.println((Employee[]) objects); // java.lang.ClassCastException 以下是利用反射实现任意类型数组拷贝的例子: private static Object goodCopyOf(Object array, int newLength) { Objects....

October 14, 2017 · Zi WANG

【Java 核心笔记】04.06. UML、类的一些要点补充

类间关系 依赖(dependence)(uses-a):例如Order对象使用Account对象查看账户的信用状态 聚合(aggregation)(has-a):例如Order对象包含了一些Item对象 继承(inheritance)(is-a) 对应的 UML 符号 有些方法学家不喜欢聚合这个概念,而更加喜欢「关联(association)」这个术语。但「has-a」更加形象,同时「关联」的 UML 符号不易区分。 以下是一个UML类图的示例: 类的一些要点补充 使用类的方法时,会隐式包含一个参数——方法名前的类对象(方法之中使用this调用),这被称为隐式(implicit)参数。其他参数称为显式(explicit)参数。 方法接收参数的形式是按值调用(call by value)。 可以通过「方法的签名(signature)」来完整地描述一个方法(方法名+参数类型,不包含返回类型),例如String类的indexOf方法 indexOf(int) indexOf(int, int) indexOf(String) indexOf(String, int) 默认域的初始化 如果没有初始化类中的域,将会被自动初始化为默认值(0、false或null)。 但局部变量不可,必须明确地初始化方法中的局部变量。 类中代码执行顺序原则: 静态优先(静态域、静态代码块) 对于非静态,顺序为:域(初始化语句)、构造代码块(初始化块)、构造方法 总结:父类静态元素 -> 子类静态元素 -> 父类非静态元素 -> 子类非静态元素 装箱和拆箱是编译器认可的,而不是虚拟机。编译器在生成类的字节码时,插入必要的方法调用。虚拟机只是执行这些字节码。 包 从编译器的角度来看,嵌套的包之间没有任何关系。 import java.time.* 对代码的大小无负面影响,但会降低人可读性。 只能使用星号(*)导入 一个 包,而不能使用import java.*或import java.*.*导入以java为前缀的所有包。 在包中定位类是编译器的工作,字节码中使用完整的包名引用其他类。 import static java....

October 14, 2017 · Zi WANG

【Java 核心笔记】04.05. 内部类

在类的内部还可以定义另一个类。如果在类 Outter 的内部再定义一个类 Inner ,此时类 Inner 就称为内部类,而类 Outter 则称为外部类。 内部类可声明为 public 或 private。当内部类声明为 public 或 private 时,对其访问的限制与成员变量和成员方法完全相同。 class Outer { // 定义外部类 private String info = "hello world"; // 定义外部类的私有属性 class Inner { // 定义内部类 public void print(){ // 定义内部类的方法 System.out.println(info); // 直接访问外部类的私有属性 } } public void fun() { // 定义外部类的方法 new Inner().print(); // 通过内部类的实例化对象调用方法 } } public class InnerClassDemo01 { public static void main(String args[]){ new Outer()....

October 14, 2017 · Zi WANG

【Java 核心笔记】04.04. 代码块

代码块就是使用 {} 括起来的一段代码,根据位置不同,可分为四类: 普通代码块 构造代码块 静态代码块 同步代码块 普通代码块 直接定义在方法中的代码块称为普通代码块。 public class Demo { public static void main(String args[]) { { // 普通代码块 int x = 30; // 属于局部变量 System.out.println("普通代码块 --> x = " + x); } int x = 100; // 与局部变量名称相同 System.out.println("代码块之外 --> x = " + x); } } // 输出 // 普通代码块 --> x = 30 // 代码块之外 --> x = 100 构造代码块 直接在类中定义的代码块,称为构造块。...

October 14, 2017 · Zi WANG

【Java 核心笔记】04.03. 匿名对象与字符串缓冲池

匿名对象 匿名对象:只在堆内存中开辟空间,不存在栈内存的引用。 由于匿名对象没有对应的栈内存引用所指向,所以使用一次之后,就等待被垃圾回收了。 例:一个单独的字符串就是一个 String 的匿名对象。System.out.println("Hi"); 字符串缓冲池 public class Test { public static void main(String[] args) { String str = "hello" ; System.out.println("hello".equals(str)) ; // true System.out.println("hello" == str); // true // String 池:Java为了优化字符串操作 提供了一个缓冲池; // str 指向字符串 “hello” ,第二句中字符串 “hello” ,因为字符串在常量池中已经存在,第二句中字符串 “hello” 就不再开辟空间。 // 所以不管是 equals 比较内容, == 比较内存地址都为 true // 但请不要使用这种方式比较字符串,不稳键 } } 下面的代码验证了我去「XXXX」面试时真的是乱吹🙈: /* * 当时我以为 JVM 的缓冲池可以实现“变量(a)连接字符串("b")可以与"ab"使用同一个堆内存” * 但是事实是并不可行 */ public class StringTest{ public static void main(String [] args){ String ab="ab"; String a="a"; // 「变量」与「变量连接字符串(匿名对象)」比较 System....

October 7, 2017 · Zi WANG

【Java 核心笔记】04.02. Override 的补充

方法的覆写 当子类定义了与父类方法名称相同、参数的类型及个数、返回值相同的方法时,就被称为方法的覆写。 被覆写的方法不能拥有比父类方法更严格的访问权限。private < default < protected < public 如果父类中的方法使用了 private 声明,而子类中同样的方法使用了 public 声明,这样属于覆写么?不属于。 class A { public void fun() { print(); } /*①*/ void print() { System.out.println("父类中的 print() 方法"); } } class B extends A { /*②*/ void print() { // 覆写的是 print() 方法 System.out.println("子类中的 print() 方法"); } } public class OverrideDemo { public static void main(String [] args) { B b = new B(); b....

October 7, 2017 · Zi WANG