一个关于javajava程序执行顺序序的问题

关于java类的执行顺序_百度知道
关于java类的执行顺序
这是一个嵌套类的例子,没什么意义,只是说明下嵌套类。
class Outer {
int outer_x = 100;
void test() {
Inner inner = new Inner();
inner.display();
class Inner {
void display() {
System.out.printl...
我有更好的答案
先后顺序如下!1.静态块2.块3.构造器4.父类构造器运行顺序为: 1. 静态块2.
父类构造器3.
本类中的块4.
本类的构造器
采纳率:59%
你去看看编译后的.class文件就会明白很多,内部类经过javac编译后会生成一个新的.class文件,然后再由ClassLoader把与之相关的所有class都会加载到内存,而之后创建对象时自然就会找到相对应的资源了。这句语句Outer outer = new Outer(); 在程序内部实质做了三件事:第一 声明了一个Outer类型的变量outer; 第二 通过new关键字创建了一个Outer对象;第三
等于号是把创建出来的Outer对象的引用(内存地址)赋给了outer变量。所以说在分析代码时一定要有内存的栈空间和堆空间的概念。(打个比喻-new动作就好比一个新对象产生时在内存的指定地盘上划分了一亩三分地给这个新生命)
本回答被提问者采纳
呵呵 跟放在前后没有关系的,你写这部分代码叫做 源代码,计算机执行的其实不是源代码,而是字节码。因此当你执行时,计算机要先做处理,把源代码转换为字节码。“ 难道java代码的执行顺序不是自上而下吗? 初学,见笑了! ”java代码执行的确是自上而下,呵呵 但是指的是函数内部代码,也就是从main函数的第一句开始执行 以此类推 到最后一句
当然了,有些代码是执行不到的因为有分支结构和循环结构比如if(true){
//B}这里B代码就执行不到不是类代码也是自上而下运行的,嘿嘿
Java代码的执行不是按照代码的顺序的,而是用到的时候再去执行,一个类里面可能会有很多方法,但大多数方法可能都是为某一个方法服务,举例说明:class test {
public static void main(String [] args) {
static a() {
static b() {
static c() {
static d() {
static f() {
}}在上面的程序中不是按照方法的顺序一次执行的,你可以考虑这样一个问题,程序都是从main()方法开始执行的,但是不是一定要将main()方法放到一个类的最前面?这个你试一下就明白了。
Outer outer = new Outer();
outer.test(); 实例化outer,就是说创建一个outer对象,然后调用了test方法,既然是调用了test方法,那么位置就没什么关系了,相当于指针,指向了test当然是使用test,就好比一碗面,我想先吃面下边的菜,我直接吃菜就行了,没必要按照顺序先把面吃完才吃菜。但是内部执行,如楼上所说是按照顺序来的。
任何一个程序都是从 void main开始执行顺序是这样的main(),然后调用test(),teat()调用inner()。
从main开始,执行父类的构造函数,然后是引用对象的构造函数(必须有new声明实际类型),然后是自己的构造函数。有static默认最先执行一次
其他6条回答
为您推荐:
其他类似问题
您可能关注的内容
java的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。一个关于Java程序关于执行顺序的问题~~~~~~先谢过各位了!
[问题点数:20分,结帖人CSDN]
本版专家分:41
CSDN今日推荐
本版专家分:135
本版专家分:1640
本版专家分:75
本版专家分:75
匿名用户不能发表回复!|
CSDN今日推荐Java中main方法,静态,非静态的执行顺序详解
  Java程序运行时,第一件事情就是试图访问main方法,因为main相等于程序的入口,如果没有main方法,程序将无法启动,main方法更是占一个独立的线程,找到main方法后,是不是就会执行mian方法块里的第一句话呢?答案是不一定
&看看下面两种最常见的情况:
  第一种情况:
    main方法在一个具有其他方法或属性的类中;
public class Test1 {
public static S
public Test1() {
public static void get() {
System.out.println("Test start");
public static void main(String[] args) {
System.out.println("main start");
Test1 bb = new Test1();
  第二种情况:
&&&&&&&&& && &main方法在一个没有其他方法或属性的类中;
public class Test {
public static void main(String[] args) {
Student stu =new Student();
  因为静态部分是依赖于类,而不是依赖于对象存在的,所以静态部分的加载优先于对象存在。
  当找到main方法后,因为main方法虽然是一个特殊的静态方法,但是还是静态方法,此时JVM会加载main方法所在的类,试图找到类中其他静态部分,即首先会找main方法所在的类。
执行顺序大致分类:
  1.静态属性,静态方法声明,静态块。
  2.动态属性,普通方法声明,构造块。
  3.构造方法。
1.1 静态:
  当加载一个类时,JVM会根据属性的数据类型第一时间赋默认值(一举生成的)。然后再进行静态属性初始化,并为静态属性分配内存空间,静态方法的声明,静态块的加载,没有优先级之分,按出现顺序执行,静态部分仅仅加载一次。至此为止,必要的类都已经加载完毕,对象就可以被创建了。
1.2 普通:
  当new一个对象时,此时会调用构造方法,但是在调用构造方法之前,(此刻1.1已经完成,除非被打断而暂停)执行动态属性定义并设置默认值(一举生成的)。然后动态属性初始化,分配内存,构造块,普通方法声明(只是加载,它不需要初始化,只有调用它时才分配内存,当方法执行完毕后内存立即释放),没有优先级之分,按出现顺序执行。最后进行构造方法中赋值。当再次创建一个对象,不再执行静态部分,仅仅重复执行普通部分。
  注意:如果存在继承关系,创建对象时,依然会首先进行动态属性进行定义并设默认值,然后父类的构造器才会被调用,其他一切都是先父类再子类(因为子类的static初始化可能会依赖于父类成员能否被正确初始化),如果父类还有父类,依次类推,不管你是否打算产生一个该父类的对象,这都是自然发生的。
下面是一道小程序:
  代码部分:
public A() {
System.out.println("A的构造方法");
public static int j = print();
public static int print() {
System.out.println("A print");
return 521;
public class Test1 extends A {
public Test1() {
System.out.println("Test1的构造方法");
public static int k = print();
public static int print() {
System.out.println("Test print");
return 522;
public static void main(String[] args) {
System.out.println("main start");
Test1 t1 = new Test1();
  运行结果:
Test print
main start
A的构造方法
Test1的构造方法
下面是一道阿里巴巴的面试题:非常经典,可以不断的改变程序的顺序,来找到执行顺序机制。
  代码部分:
public class Text {
public static int k = 0;
public static Text t1 = new Text("t1");
public static Text t2 = new Text("t2");
public static int i = print("i");
public static int n = 99;
public int j = print("j");
print("构造块");
print("静态块");
public Text(String str) {
System.out.println((++k) + ":" + str + "
i=" + i + "
public static int print(String str) {
System.out.println((++k) + ":" + str + "
i=" + i + "
return ++i;
public static void main(String args[]) {
Text t = new Text("init");
&  运行结果:
总结:只要按照这个步骤,遇到这一类问题就可以解决了。&&&&&
&&&&    & 1-3:类加载过程,不涉及构造方法
&&&&&     1-5: 实例化过程,涉及构造方法
  1.类中所有属性的默认值(一举而成)
  2. 父类静态属性初始化,静态块,静态方法的声明(按出现顺序执行)
  3. 子类静态属性初始化,静态块,静态方法的声明 (按出现顺序执行)
  4.& 调用父类的构造方法,
      首先父类的非静态成员初始化,构造块,普通方法的声明(按出现顺序执行)
      然后父类构造方法
  5.& 调用子类的构造方法,
      首先子类的非静态成员初始化,构造块,普通方法的声明(按出现顺序执行)
      然后子类构造方法
   (注意:类加载过程中,可能调用了实例化过程(因为static可以修饰方法,属性,代码块,内部类),此时则会暂停类加载过程而先执行实例化过程(被打断),执行结束再进行类加载过程,上面阿里那道面试题就是典型的暂停类加载。
下面附加一个小程序来显示新建对象时属性的四个过程:
public class Test {
public static void main(String[] args) {
Student stu = new Student("zhangan", 21);
class Student {
public String name = "李寻欢";
public int age = 20;
public Student(String name, int age) {
this.name =
this.age =
阅读(...) 评论() 上传我的文档
 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
Java代码执行顺序分析
下载积分:100
内容提示:Java代码执行顺序分析
文档格式:DOC|
浏览次数:308|
上传日期: 15:18:32|
文档星级:
全文阅读已结束,如果下载本文需要使用
 100 积分
下载此文档
该用户还上传了这些文档
Java代码执行顺序分析
关注微信公众号&今天我给大家讲解一下java的的错误和异常处理机制以及相关异常的执行顺序问题。如有不足的地方,欢迎批评指正~
1、首相简单介绍一下java中的错误(Error)和异常(Exception)
& & 错误和异常的介绍:
&&& 在java.lang软件包中有一个java.lang.Throwable类,这个类是java中所有错误和异常的超类。
&&& 在java中错误和异常的继承主要有两个: 分别为Error和Exception 这两个。
&&&&Error:&&&&&&&& 是java中所有错误类的父类,就是jvm出现错误,以及系统蹦溃等现象,这些错误没办法通过程序来处理,对于系统错误,一般不需要开发
&&&&&&&&&&&&&&&&&&&& 人员处理(也无法处理),&比如内存溢出(Out of Memory)和线程死锁等系统问题。所以在程序中需要使用catch来捕捉处理这类的错误或者使用throw来抛出相
&&&&&&&&&&&&&&&&&&&& 关的异常。
&&& Exception:& 又可以分为checkedException(编译时异常) 和RuntimeException(运行时异常) 这两种异常,checkedException异常在进行编译的
&&&&&&&&&&&&&&&&&&&& 时候就可以知道会不会发生异常,如果不对这些异常进行抛出、捕获的话就不能通过编译,如在使用java的io读取文件的时候,可能会会出现
&&&&&&&&&&&&&&&&&&&& 所读取的文件不存在的情况&对于,对于这类编译时的异常必须手动去处理它们(捕获或者抛出)。否则的话是无法正常通过编译器的。&而
&&&&&&&&&&&&&&&&&&&&&RuntimeException就是运行的时候出现的异常,在之前你是没办法确定是不是会出现异常。这类异常仅仅在程序运行的过程中才会发现。
&&&&&&&&&&&&&&&&&&&&&比如数组下标越界(ArrayIndexOutOfBoundsException),强制转换报错(ClassCastException,一部分),空指针异常(NullPointerException)
&&&&&&&&&&&&&&&&&&& 除数为零(/ by zero)&对于这类运行时的异常是否抛出, 由用户根据自身的情况&决定是否抛出异常。java并不强制要求用户&一定处理。
&& 2、异常处理过程
& 把会出现异常的程序段放在try中,当抛出异常的时候就会在系统中生成一个异常对象,然后进行查找捕获这个异常,然后进行处理这个异常,处理之后接着执行下面的程序。
出现异常之后如果没有进行捕获处理系统就会直接将这个异常栈的跟踪信息直接打印出来之后就结束这个程序的执行。
&&&& 对于异常的处理方式有两种分别为:try{}catch{}finally{}和throws下面简单说一下这两者的区别和联系
&&&& 请先看下面的例子:
public class Test{
public static void main(String[] args){
Test2 test2 = new Test2();
System.out.println("invoke the method begin!");
test2.method();
System.out.println("invoke the method end!");
}catch(Exception e){
System.out.println("catch Exception!");
class Test2{
public void method() throws Exception{
System.out.println("method begin!");
int a = 10;
int b = 0;
int c = a/b;
System.out.println("method end!");
很明显,答案出来了:
invoke the method begin!
method begin!
catch Exception!
&&&& 对于try{}catch{}finally{}而言,用户可能确定知道代码会出现相关的异常,把有可能出现问题的地方放到try中去执行,如果一旦出现异常,立刻终止当前代码的继续
&&&& 执行,转而去执行catch{}里面的内容。对于这类异常用户已经处理了,不会在向上抛出。
&&& 对于throws而言,一般使用在方法名的后面,使用throws关键字的时候,一般是开发者不确定出现什么异常或者出现异常的情况可能有多种。这时开发者在方法后面加  &&&&throws关键字抛出相关的异常。对于调用该方法的其它开发者者必须捕获这个异常或者继续throws这个异常,把这个异常传递下去,交给其对应的父类去处理。
&&& 需要注意throw关键字和throws关键字是有区别的。throw一般用于方法中,抛出用户自定义的异常如 throw new MyException("用户自定义异常")。
&&& 而throws是用在方法名的后面,通知使用该方法的人,当前方法有可能抛出异常。
&&&& 如果简单的理解可以这样看:对于throws可以理解为抛出,抛出给别人,自己不处理。而try{}catch{}finally{}则可以理解为截断,开发者自己处理这个异常。
&&&& 3、异常处理的执行顺序(针对try{}catch{}finally{}而言)
&&&& 对于try{}catch{}finally{}而言,,它们的执行顺序很简单,如果在try{}中捕获相应的异常,中断当前代码的执行,转而去执行catch{}中的内容,最后去执行
&&& finally{}中方法,一般来说finally中的方法都是会被执行的,其中finally中很大程度上用于资源的释放。
&&& 下面讲解一些我们java程序员需要注意的地方。
&&&&&&&&& a、finally中的代码总是会执行吗?
&&&&&&&&&&&& 答:no,如果一个方法内在执行try{}语句之前就已经return了,那么finally语句指定不会执行了。因为它根本没有进入try语句中
&&&&&&&&&&&&&&&&&&&&&&& 如果在一个try语句中调用System.exit(0);方法,那么就会退出当前java虚拟机,那么finally也就没有执行的机会了。
&&&&&&&&& b、finally在return之前执行还是在return之后执行?
&&&&&&&&&&& 答:很多人可能会说在return执行之前执行。我的答案是在return中间执行,是不是很特别,请按下面的例子:
&&&&&&&&&&&
package com.yonyou.
class Test{
public static void main(String[] args) {
System.out.println(method());
public static int method(){
}catch(Exception e)
  请问输出的结果是多少呢?
&&& 正确答案是:1
&& 下面我来讲解一下这个程序的执行过程,
&&& 首先程序在执行到try{}语句中的return方法后,就会先返回相应的值,并把相应的值存储在一个临时栈中去保存这个结果。这时临时栈中存储的值为1。
&&& 但是程序不会立刻返回,转而回去执行finally中的方法,++x,在finally执行完后,方法全部执行完,这时会再次调用return方法,注意这时
&& 不在是返回值,而是告诉主调程序,被调程序已经执行完了,你可以接着去执行你主程序的其它方法了。但是请注意,此时返回的值还是原来保存在临时
&& 栈中的值1。
&为了更好的理解这个问题,我们看下面的程序:
package com.yonyou.
class Test{
public static void main(String[] args) {
System.out.println(method());
public static int method(){
}catch(Exception e)
  这时的正确答案又是多少呢?
&&&& 没错是2,这里仅仅需要注意的是在try{}语句中执行到return 1 会在临时栈中存储值为1的变量。接着回去执行finally里面的内容,这时执行finally中的return 2;方法,这时
&&& 临时栈中的值就是变为 2,会覆盖原来临时栈中的值1.所以它的返回值为2。
&&&& c、finally方法是必须的吗?
&&&&&&&& 不是,开发者可以根据自身的情况去决定是否使用finally关键字。
&&& 好吧,今天就先到这里吧。
&&&&&&&&&&&&&&&&&&&&&&&
阅读(...) 评论()}

我要回帖

更多关于 java程序执行顺序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信