先加载静态属性,值为默认,然后static代码块(),再加载代码块,最后构造函数,有多个就按顺序加载。(属性和代码块那个在前那个先加载,属性如果在代码块后面那么代码块中只能赋值不能访问。)
如果有子类,先加载父类static代码块,然后子类static代码块,父类代码块,构造函数,子类代码块,构造函数。
没有初始化的话,属性默认。int默认0,对象默认null,boolean默认false.
static只执行一次,其他的每次实例化都会加载一遍。
static方法不能用this,因为this执行的是对象,static比对象早。
可以用this(...)来访问另一个构造方法,这样就能共享一个构造方法。
public class Test {
public static int k = 0;
public static Test t1 = new Test("t1");
public static Test t2 = new Test("t2");
public static int i = print("i");
public static int n = 99;
public int j = print("j");
{
print("构造快");
}
{
print("静态块");
}
public Test(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
++i;
}
public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++i;
return ++n;
}
public static void main(String[] args) {
Test t = new Test("init");
}
}
代码分析:
先加载加载静态属性;
public static int k = 0;
然后第二个静态属性
public static Test t1 = new Test("t1");跳到构造函数,执行构造函数前,先加载非静态属性,然后非静态构造快。
然后第三个静态属性 同上;
然后静态属性i;
最后静态属性n;
没有静态代码块,执行main函数,创建一个对象
1:j i=0 n=0
2:构造快 i=1 n=1
3:静态块 i=2 n=2
4:t1 i=3 n=3
5:j i=4 n=4
6:构造快 i=5 n=5
7:静态块 i=6 n=6
8:t2 i=7 n=7
9:i i=8 n=8
10:j i=9 n=99
11:构造快 i=10 n=100
12:静态块 i=11 n=101
13:init i=12 n=102
java中方法的参数是值传递,不会改变简单类型的值,会改变对象的内容,不会改变对象的引用。
StringBuffer和StringBuilder的区别
StringBuffer多线程安全,StringBuilder执行速度快,他们都是可以改变值的。String是不能改变的,只能改变引用的值。
switch--case在1.7后除了整数和枚举,还可以用String。
简单类型相加有double结果就是double,没有double有float结果就是float,没有float有long就是long,没有就是int。
char占两个字节,所以可以存储汉字。
==和equals的区别
对于简单类型,==就是判断值是不是相等,没有equals.
对于引用类型,==就是判断引用的是不是同一个位置,equals在Object中是判断是否在同一位置,但是其他的类比如String就重写了这个方法,把equals变为判断是不是值相等。
String a ="abc";
String b = "abc";
String c=new String("abc");
a==b为true,a.equals(c)为true,a==c为false;因为a和b是引用的同一个“abc”;而c是新建了一个对象,跟“abc”不在同一个位置。同理“abcdef”.substring(0,3)等操作也是新建了一个对象而不是引用“abc”。String d = b;这是引用的“abc”.
&与,|或,^异或,~非,等运算要变为二进制后运算。目前不知道~怎么转换为负数。
>>右移,用符号位填充高位,>>>右移,用0填充高位,<<左移,没有<<<
+=,-=,*=是右结合运算符,所以a+=b*=c+=d----->a=a+(b*(c+d));