java基本知识点(二)
1.String字符串
String与StringBuffer,StringBuilder
public class abs{
public static void main(String[] args) {
String a = "hello"; /*@1*/
String b = "hello"; /*@2*/
String c = new String("hello"); /*@3*/
System.out.println(a==b); /*@4*/
System.out.println(a.equals(b)); /*@5*/
System.out.println(a==c); /*@6*/
System.out.println(a.equals(c)); /*@7*/
change(a); /*@8*/
System.out.println(a); /*@9*/
String d = a.substring(1); /*@10*/
System.out.println(d); /*@11*/
StringBuffer e = new StringBuffer(); /*@12*/
e.append("helloS");
System.out.println(e);
changeStringBuffer(e);
System.out.println(e);
StringBuilder f = new StringBuilder(); /*@13*/
f.append("helloSB");
System.out.println(f);
changeStringBuilder(f);
System.out.println(f);
}
public static void change(String test){
test = "helloWord";
}
public static void changeStringBuffer(StringBuffer test){
test.append("helloword");
}
public static void changeStringBuilder(StringBuilder test){
test.append("helloword");
}
}
下面是运行结果:
下面对其进行分析:
1)首先1和2处的a和b,在生成String a的时候,在String池中创建Hello,然后再创建b的时候,只是把Hello的引用复制一份放入栈内存b中。由于a和b的内容都是池中Hello的引用,也就是Hello的地址,所以4和5处的结果都是true。
2)3处在创建String的时候会在String池中查找是否有Hello字符,A:如果没有,创建一个Hello放入池中,接着在堆中新建一个Hello,最后在栈中添加一个堆中Hello的引用。 B:如果有的话,直接在堆中新建一个Hello,然后在栈中添加一个堆中Hello的引用。 为什么New 这种方式,会在堆中新建一个,因为如下代码:
/**
* Initializes a newly created {@code String} object so that it represents
* the same sequence of characters as the argument; in other words, the
* newly created string is a copy of the argument string. Unless an
* explicit copy of {@code original} is needed, use of this constructor is
* unnecessary since Strings are immutable.
*
* @param original
* A {@code String}
*/
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
在String的构造方法中,它的参数就是一个String,就是说在未创建String之前,必须有另外一个String作为参数,然后再重新生成一个内容相同的String。所以6处返回的结果是false,而7处比较内容,返回的结果是true。
3)change函数,8处传递给change的是一个String的引用,这是没错的,按理说应该可以对String进行更改,但是如下代码:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
表明String是final类型,是不可更改的,所以在String中找不到像StringBuffer那样可以对自己的内容进行修改的函数(如append),所以change函数中,test=“helloWorld”视图对其指向的内容进行更改并没有生效,而是新建了一个helloWorld然后指向它,原来的hello没有改变。
4) 12和13处,在创建一个实例后,实例的值是可以通过append等函数来改变的。 所以能够通过传递引用来改变其值。vivo画图表示如下:
2 Java异常
try、catch、finally语句块的执行顺序:
1)当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;
2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,
此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;
3)当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序
将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异
常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;
4)try...catch嵌套的问题:
每次进入try语句,异常的前后关系都会被压入堆栈。如果一个内部的try语句不含特殊异常的catch处理程序,堆栈将弹出,下一个try语
句的catch处理程序将检查是否与之匹配。这个过程将继续直到一个catch语句匹配成功,或者是直到所有的嵌套try语句被检查耗尽。如果
没有catch语句匹配,Java的运行时系统将处理这个异常。