请在不用工具运行的情况下写出下面main方法执行的结果?public class Test {
private int ix = 50;
private Test( int ix){
System.out.println(ix);
}
static {
System.out.println("test2");
}
{
System.out.println("test3");
} public static void main(String[] args) {
Test t;
t = new Test(1);
Test t2;
t2 = new Test(2);
}
}
private int ix = 50;
private Test( int ix){
System.out.println(ix);
}
static {
System.out.println("test2");
}
{
System.out.println("test3");
} public static void main(String[] args) {
Test t;
t = new Test(1);
Test t2;
t2 = new Test(2);
}
}
test3
1
test3
2
test3
1
2
test3
1
test3
2
test3
1
test3
2
System.out.println("test2");
} {
System.out.println("test3");
}
這種寫法有什么意義?
{
System.out.println("test3");
}
这句很难理解(类里加这种代码有意义吗?),既不为静态方法又不为构造方法。java是如何处理其加载的?请解释一下,谢谢。
显式初始化代码在构造函数被调用之前被执行;
System.out.println("test3");
}
属于非静态代码块把!
static {
System.out.println("test2");
}{
System.out.println("test3");
} 输出 test2 ,test3;再执行
Test t;
t = new Test(1);
System.out.println(ix); 输出 1;再执行{
System.out.println("test3");
} 输出 test3;最后
Test t2;
t2 = new Test(2); 输出 2;test2
test3
1
test3
2
test3
1
test3
2
1.一般是先执行类中的静态块.再执行类中的普通语句块 也就是上述的{}(非静态块)标识的语句块.
最后加执行构造块.
2.类的静态块只执行一次,而对于{}(非静态块)块,每个对像生成后都会进行初始化.
所以LZ的例子,执行的过是
test2
test3
1
test3
2
最后才是構造方法,大家把代碼適當刪除測試就知道了!
http://topic.csdn.net/u/20080510/13/625dc9d3-7cfa-4aca-ac81-4a64446e378d.html
test3
1
test3
2
很细致的问题
static main(){} 表示静态方法,
在类加载时 static 优先级高。
所以不管怎样,类加载时:先静态块,再静态(属性/方法);大括号 {} 标示:创建对象时的初始化快,优先级比构造方法高,
所以,创建对象时:先初始化块,后构造方法;程序执行过程分为3步:
1.
加载所有 static 初始化块,这里只有一个;
static
{
System.out.println("test2");
}[/color]
输出:test2
2.
先加载所有 [color=#00CCFF]static (方法/属性),后加载所有非 static (方法/属性),
找到 main() 方法;
3.
main() 方法中只创建两个对象,而创建对象时,先初始化块,后构造方法;
Test t = new Test(1); 和 Test t2 = new Test(2);
执行形同的代码块:
{
System.out.println("test3");
}
private Test( int ix){
System.out.println(ix);
}
输出:[/color]
test3
1
test3
2请各位指教,谢谢!
公布一下正确答案:
test2
test3
1
test3
2 具体解释请看35楼解释。结帖了。
大括号 {} 标示:创建对象时的初始化快,优先级比构造方法高,
所以,创建对象时:先初始化块,后构造方法; 很不理解上面这句,为什么非要把你所说的初始化块跟构造方法放在一起说?难道不初始化对象,就不会执行那个初始化块了吗?(恐怕不是吧!)
public class Test
{
private int ix = 50;
private Test( int ix)
{
System.Console.writeln(ix);
}
static
{
System.Console.writeln("test2");
}
{
System.Console.writeln("test3");
}
}
其中
static
{
System.Console.writeln("test2");
}
{
System.Console.writeln("test3");
}
这两句不合法啊,谁能讲一下c#里面为什么不合法?我想知道这里的c#和java的区别
答:记住:千万不要认为对象初始化块即{}比构造器器先执行。这是很错误的认识。详细的执行过程是:第1步:开始运行该程序Test时,类Test.class首先装入内存(此时:进行类Test的初始化,即:运行static{...},然后:再调用 static 的main(....))第2步:调用new Test(1)则:(由于类Test已在内存,故不再进行类的初始化)
第2.1步:执行该构造器的第一条语句:super()。(对该对象中所包含的父亲Object对象进行初始化)
第2.2步:这时才进行:对象数据成员private int ix = 50;和对象的初始化块{
System.out.println("test3");
} 的执行。它们按照定义时的顺序依次进行运行
第2.3步:这时再运行构造器中语句:System.out.println(ix); 第3步:调用new Test(2)则:(由于类Test已在内存,故不再进行类的初始化)
第3.1步:执行该构造器的第一条语句:super()。(对该对象中所包含的父亲Object对象进行初始化)
第3.2步:这时才进行:对象数据成员private int ix = 50;和对象的初始化块{
System.out.println("test3");
} 的执行。它们按照定义时的顺序依次进行运行
第3.3步:这时再运行构造器中语句:System.out.println(ix);
因此:运行到此时,屏幕上的结果是:test2 test3 1 test3 2
private int ix = 50;
private static String name = "wanbo169";
private Test( int b){ //4.执行构造函数
System.out.println("进入>>>>>>>>>>>>>>");
System.out.println("某对象构造函数");
System.out.println(ix);
ix = b;
System.out.println(ix);
System.out.println("");
} static {
System.out.println(name); //???
System.out.println("进入>>>>>>>>>>>>>>");
System.out.println("类static块");
System.out.println("");
} {
System.out.println("进入>>>>>>>>>>>>>>>>>>");
System.out.println("某对象的初始化块");
}
public static void main(String[] args) {
System.out.println("进入>>>>>>>>>>>>>>>>>>");
System.out.println("main函数");
System.out.println("");
Test t = new Test(1);
Test t2 = new Test(2);
}
}
思考下例:public class TestInitial {
private int x=1;//数据成员初始化
{//对象初始化块
x=2;
}
public TestInitial()//这是构造器
{
this(x);//若你认为:先做对象初始化块,再做构造器。那么问:此处的实参x的值是什么?
}
public TestInitial(int y)
{}
}
问:若你认为:先做对象初始化块,再做构造器。那么问:上述的实参x的值是什么(x值是2,是1,还是其它)?还是没有值,就不行呢?
package com.sytdc.cxl;public class StaticTest { public StaticTest(int i){
System.out.println("constructor " + i);
}
//执行一次
static {
System.out.println("static ");
}
{
System.out.println(" no static ");
}
public static void main(String args[]){
StaticTest st;
System.out.println("--------- ");
//st = new StaticTest(1);
// StaticTest st2;
// System.out.println("--------- ");
// st2 = new StaticTest(2);
}
}
执行结果
static
---------
也就是说建立类的实例的时候,只是执行static静态代码快,并且只执行一次。当我对对象st进行new的时候
public static void main(String args[]){
StaticTest st;
System.out.println("--------- ");
st = new StaticTest(1);
这个时候执行结果:
static
---------
no static
constructor 1
也就是当对对象进行new的时候,才执行非静态代码快,然后执行构造函数。无论建立几个类的对象,static只加载一次,而非静态代码快,只要进行new操作,就执行。
看下面的代码
package com.sytdc.cxl;public class StaticTest { public StaticTest(int i){
System.out.println("constructor " + i);
}
//执行一次
static {
System.out.println("static ");
}
{
System.out.println(" no static ");
}
public static void main(String args[]){
StaticTest st;
System.out.println("--------- ");
st = new StaticTest(1);
StaticTest st2;
System.out.println("--------- ");
st2 = new StaticTest(2);
}
}
执行结果
static
---------
no static
constructor 1
---------
no static
constructor 2以上是我的理解,请大家多指教。
基于上面的知识,我们可以很容易理解为什么被static修饰的成员为什么没有this了.静态代码块仅在加载类时执行一次.
当我们定义一个Test T 时,Jvm就开始把这个类装入进内存中,当装入内存时即开始初始化静态成员,由于静态成员
要被所有的实例共享,所以在创建类的实例时就必须提前被初始化.所以这时打印出了test2.第二步:我们再隐解下new关键字,使用new关键字会产生下列结果:
1:为新对象分配空间并初始化为0或null
2:执行显示的初始化工作.
3:执行构造方法.
4:该变量被赋值为堆内存中新对象的引用.
如在Test t = new Test(2);
中,先为引用变量T分配空间,而t中没有任何值,即为null,使用new关键字后,
它暗示了空间的分配和始始化 此时执行成员变量ix=50这种,构造方法是最后一个被执行的,它
可以覆盖默认的初始化.
代码块中的代码会被当做类成员进行初始化,所以第二步会执行打印出test3
第三步:这时成员初始化工作完成了,开始执行构造方法,即打印出了1第四步: 当再次定义Test t2时,由于说过了,静态成员只会被加载一次,所以不再执行静态代码块中的内容,
即不会再次打印出test2 了,按照上面所说的顺序,又开始进行初始化成员工作,打印出test3.最后构造方法打印出2执行结果:test2 test3 1 test3 2
test3
1
test3
2
System.out.println("test3");
}
属于非静态代码块把!
test3
1
test3
2
Press any key to continue...
//呵呵,我的是准确的