9-28 程宗武
9-28
一、知识点总结
String类中常用的API
**1、compareTo(String anotherString) ** compareTo 按字典顺序比较两个字符串
//1、compareTo(String anotherString)
String str = "ABCDE";
System.out.println(str.compareTo("ABCDEH"));
相等时返回0 ,当被比较字符串的Unicode码 大于比较的字符串的Unicode码时,返回正整数。反之返回负整数。
String str = "A";
System.out.println(str.compareTo("Z")); //-25
当两个字符串中较短字符串的内容和另一个字符串的部分内容相同时,返回的是两个字符串长度的比较
结果。
String str = "AB";
System.out.println(str.compareTo("ABZ"));// -1
**2、concat(String str) ** 将指定的字符串连接到该字符串的末尾
String str = "AB";
System.out.println(str.concat("CD")); //ABCD 这里是新建的了ABCD字符串放到常量池,并不是在原有的内容上连接。
3、itern 返回字符串的规范表示
当调用intern方法时,如果池已经包含与equals(Object)
方法确定的相当于此String
对象的字符串,则返回来自池的字符串。 否则,此String
对象将添加到池中,并返回对此String
对象的引用。
String str = "ABCD";
String intern = str.intern();
System.out.println(intern == str); // true 这种情况返回的是池里面已经有了的字符串
String str = "AB";
String str1 = str + "CD";
String intern = str1.intern();
String str2 = "ABCD";
System.out.println(intern == str2); // true 这种情况是池里面没有"ABCD",因此返回了一个字符串ABCD的引用,当再次创建 str2 时,调用了euals方法,发现池里面已经有了一个"ABCD"字符串的引用,因此再创建str2时,直接返回这个引用。intern 和 sr2 指向的是同一个引用,因此 == 比较的结果为true
String str = "AB";
String str1 = new String(str + "CD");
String intern = str1.intern();
String str2 = "ABCD";
System.out.println(intern == str2); // true 这种方式创建的方式和 上面的第二种差不多。
大致的内存图分析如下:
包装类
Integer integer = 1;
add(integer); // 此时的Integer传到add方法中过后自动拆箱变成了基本数据类型的自增,并没有对Integer integer 包装类型做出更改,因此返回的结果还是1
System.out.println(integer);//1
public static void add(Integer i){
i++;
}
包装类的默认缓冲区
Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1 == i2); //true
Integer i3 = 128;
Integer i4 = 128;
System.out.println(i3 == i4); //false
// Integer类型的默认缓冲区为 -128 - 127 因此 127在常量池中有,直接找到常量池中的引用,而 128 则是新创建的两个包装类的引用,因此==的比较结果为false.
二、考试纠错
1、java中的关键字
abstract | assert | boolean | break | byte |
---|---|---|---|---|
case | catch | char | class | const |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | strictfp | short | static | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
main 只是主函数方法的一个入口,并不是Java中的关键字
2、变量的命名规范
变量命名只能使用:字母 数字 $ _
变量第一个字符只能使用:字母 $ _
变量第一个字符不能使用:数字
3、继承
public class HumanTest {
public static void main(String[] args) {
new SubClass();
}
}
class SuperClass{
public static int a = 1;
public static int b = 1;
static{
System.out.println("SuperClass --> static");
}
{
System.out.println("SuperClass --> instance");
}
public SuperClass(){
System.out.println("SuperClss()");
show();
}
public void show() {
System.out.println(this.a + " , " + this.b);
}
}
class SubClass extends SuperClass{
public static int a = 2;
public int b = 2;
static{
System.out.println("SubClass --> static");
}
{
System.out.println("SubClass --> instance");
}
public SubClass(){
System.out.println("SubClass()");
show();
}
@Override
public void show() {
System.out.println(this.a + " , " + this.b);
}
}
SuperClass --> static
SubClass --> static
SuperClass --> instance
SuperClss()
2 , 0
SubClass --> instance
SubClass()java
2 , 2
这里在new SubClass()
对象的时候,首先执行 new
。虚拟机发现方法区中并没有该类的信息,就会先去加载该类,在加载的时候发现该类有父类(Java
中除了java.lang.Object
没有父类,其他类都会有父类)即SuperClass
,则会先加载该类的父类(SuperClass
),然后进行父类类(static
)变量的初始化(包括准备阶段的默认初始化(零值
)和初始化阶段的显示初始化(clinit
也就是static
初始化或者说是static
块)。然后进行子类类(static
)变量的初始化,类变量初始化完毕。
接着进行对象的创建,进入子类构造函数(SubClass()
),在子类构造函数第一行会调用递归父类构造函数(SuperClass
),进入父类构造函数之前会先进行父类实例变量初始化,即给非静态成员变量初始化(实例初始化)并运行代码块,然后进入父类构造函数执行,当运行show()
方法时发现子类对其进行了覆盖,那么运行子类的show()
方法,由于子类还没有进行实例变量的显示初始化,只能输出2
和 0
,父类构造函数运行结束返回到子类构造函数,此时先会进行子类实例变量的显示初始化(实例初始化),运行了子类代码块,接着运行子类构造函数,接着运行show()
,这时子类实例变量都进行了显示初始化,输出2
和 2
。
3、心得
当遇到程序的输出结果和我们预期的不一样的情况时,要点进去源码进行查看,了解这个方法的执行过程,才能有效的定位错误的根源。
近期评论