一、String 和 StringBuffer String 定义的是字符串常量,其値一旦定义就不再改变,如下: String s =“ABC”; s =s.subString(2); //会重新生成一个字符串对象 以上两句执行后在内存中会产生“两”个字符串对象 一个”ABC”,另一个是 s 指向的”AB”(注意 s 已不再指向”ABC”) StringBuffer 定义的是字符串变量,其值可以改变,如下: StringBuffer s1= new StringBuffer(“ABC”); S1 =s1.subString(2); 以上两句执行后在内存中只产生“一个”字符串对象: s 指向的”AB”; 二、String s = new String(“abc”) 产生了几个对象 该语句会产生 2 个字符串对象: 一个是通过“ ”方式在编译期产生,存放在常量池 一个是通过 new 方式在运行期产生,存放在堆内存中 三、 java 中的参数只能“按值”传递,且传递的是值的copy 如是基本类型,则传递的是基本类型的副本 如是引用类型,则传递的是引用本身的副本 四、java 中的构造函数 1. 构造函数不能被继承 2. 每一个类都至少有一个构造函数,自己不定义,编译器也会给分配一个默认的不带参数的构造函数 3. 子类的构造函数一定会调用父类的构造函数,通过 super()调用,或显式或隐式,显式调用的父类构造函数必须存在; 如果没有显式调用则编译器会自动在子类的构造函数第一行处加上 super()这个隐式调用,这时要求父类一定要有不带参数的构造函数存在(如果父类自己定义了构造函数,但带有参数,编译时会报错) 五、java 中的异常处理 1. java 中的异常分运行时异常和非运行时异常,运行时异常由运行时系统捕获并处理(编译正常),非运行时异常必须由处理(抛出或捕获) 2. 异常机制中try{ }后一定要跟 catch 吗? 不一定,但必须跟finally。也就是 catch 和 finally 必须跟其中一个。因为这样可以保证即使发生了异常,finally 里面的代码一定会被执行。可以用来释放一些自己占用的资源,然后让调用者处理异常。 3. 异常中的 finally 一定会执行,哪怕一个方法中有 return 语句,也是在异常处理后才返回 4. 异常的抛出可以先子类再父类,如果子类捕获了,则父类就不再捕获;但是不能先父类再子类,那样会导致编译出错 5. 异常处理后,程序继续执行 六、equals,和= = equals:比较两个对象的内容是否相等 = =:比较的是两个引用是否指向同一对象(比较的地址) String的存储特性会对以上的判定规则产生影响: String通过“”方式生成的对象会存储在常量池中,常量池有一个重要的特点就是共享,比如 String s = “X”; 在把”X”放常量池之前 jvm 会检测常量池中是否存在和“X"相同的对象,如果已经存在则直接把引用指向已存在的对象,不再为”X”分配空间,好处是节约了空间 例子: String s1 = "hello"; Strings2 = "hello"; System.out.println(s1==s2);//true System.out.println(s1.equals(s2)); //true String ss1 = "hello"; Stringss2 = "world"; Stringss3 = "helloworld"; System.out.println(ss3.equals(ss1+ss2));//true /*如果是字符串变量相加,先开空间,再相加存储。如果是字符串常量相加,先加,在常量池里面找,如果有就返回常量池里面的地址。否则,就创建新的存储空间。 */ System.out.println(ss3== ss1 + ss2);// false System.out.println(ss3== "hello" + "world"); // true 七、数值类型的转换 实心箭头表示无信息丢失的转换;空心箭头表示有精度损失 |