java 执行顺序_Java代码执行顺序

程序中代码执行的顺序非常重要,稍有不慎便会是程序运行出错,那么我将结合实例来分析代码中的执行。

名词解释

首先了解几个名词:

非静态代码块

直接由 { } 包起来的代码,称为非静态代码块

静态代码块

直接由 static { } 包起来的代码,称为静态代码块

形参

比如你定义一个函数void add(int a, int b),这里的a和b就是形参。

当你进行函数调用的时候,add(1, 2),这里的1和2就是实参。

向前引用

所谓向前引用,就是在定义类、接口、方法、变量之前使用它们。

成员变量

在类体里面定义的变量称为成员变量;

如果该成员变量有 static 关键字修饰,则该成员变量称为 静态变量 或 类变量;

如果该成员变量没有 static 关键字修饰,则该成员变量被称为 非静态变量 或 实例变量。

局部变量

形参、方法内定义的变量、代码块中定义的变量,都属于局部变量。

类变量 (静态变量)

可以向前引用

变量属于类本身

类变量不依赖类的实例,类变量只在初始化时候在方法区中被分配一次空间,无论类的实例被创建几次,都不再为类变量分配空间

通过类的任意一个实例来访问类变量,底层都将将其转为通过类本身来访问类变量,它们的效果是一样的

一旦类变量的值被改变,通过类或类的任意一个实例来访问类变量,得到的都将是被改变后的值

将在类的初始化之前初始化

实例变量(非静态变量)

不能向前引用,如果向前引用,则称为非法向前引用,这是不允许的

变量属于类的实例对象

随着类的实例被创建而分配内存空间

实例演示

public class Parent {

public int parentNum=0;

public static int staticParentNum=0;

{

System.out.println("Parent---执行非静态代码块了1!");

}

{

System.out.println("Parent---执行非静态代码块了2!");

}

static{

System.out.println("Parent---执行静态代码块了1!");

}

static{

System.out.println("Parent---执行静态代码块了2!");

}

public Parent(){

System.out.println("Parent---无参构造函数!");

}

public Parent(int parentNum){

this.parentNum=parentNum;

System.out.println("Parent---有参构造函数!");

}

public void ParentMethod(int parentNum){

this.parentNum=parentNum;

System.out.println("Parent---非静态方法/parentNum="+parentNum);

}

public static void staticParentMethod(int staticParentNum){

Parent.staticParentNum=staticParentNum;

System.out.println("Parent---静态方法/staticParentNum="+staticParentNum);

}

}

public class Child extends Parent{

public int childNum=0;

public static int staticChildNum=0;

{

System.out.println("Child---执行非静态代码块了1!");

}

{

System.out.println("Child---执行非静态代码块了2!");

}

static{

System.out.println("Child---执行静态代码块了1!");

}

static{

System.out.println("Child---执行静态代码块了2!");

}

public Child(){

super();

System.out.println("Child---无参构造函数!");

}

public Child(int childNum){

super(childNum);

System.out.println("Child---有参构造函数!");

}

public void childMethod(int childNum){

this.childNum=childNum;

System.out.println("Child--非静态方法/childNum="+childNum);

}

public static void staticChildMethod(int staticChildNum){

Child.staticChildNum=staticChildNum;

System.out.println("Child---静态方法/staticChildNum="+staticChildNum);

}

}

package test;

public class Test {

// static{

// System.out.println("Test---静态代码块!");

// }

public static void main(String[] args) {

int key=10;

switch (key) {

case 0:

Parent parent=new Parent();

break;

// Parent---执行静态代码块了1!

// Parent---执行静态代码块了2!

// Parent---执行非静态代码块了1!

// Parent---执行非静态代码块了2!

// Parent---无参构造函数!

// 说明:先加载静态代码块,后加载非静态代码块

case 1:

Child b= new Child();

break;

// Parent---执行静态代码块了1!

// Parent---执行静态代码块了2!

// Child---执行静态代码块了1!

// Child---执行静态代码块了2!

// Parent---执行非静态代码块了1!

// Parent---执行非静态代码块了2!

// Parent---无参构造函数!

// Child---执行非静态代码块了1!

// Child---执行非静态代码块了2!

// Child---无参构造函数!

// 说明:创建子类,会先执行父类,先执行父类静态——>子类静态——>父类非静态——>父类构造

//——>子类非静态——>子类构造

case 2:

Child c= new Child(4);

//这个构造函数中指明了调用父类的有参构造函数,若不指定,则调用父类无参构造函数

break;

// Parent---执行静态代码块了1!

// Parent---执行静态代码块了2!

// Child---执行静态代码块了1!

// Child---执行静态代码块了2!

// Parent---执行非静态代码块了1!

// Parent---执行非静态代码块了2!

// Parent---有参构造函数!

// Child---执行非静态代码块了1!

// Child---执行非静态代码块了2!

// Child---有参构造函数!

说明:静态代码块或非静态代码块执行顺序,按照代码前后编写顺序。

case 3:

Child d= new Child();

Child e= new Child(4);

break;

// Parent---执行静态代码块了1!

// Parent---执行静态代码块了2!

// Child---执行静态代码块了1!

// Child---执行静态代码块了2!

// Parent---执行非静态代码块了1!

// Parent---执行非静态代码块了2!

// Parent---无参构造函数!

// Child---执行非静态代码块了1!

// Child---执行非静态代码块了2!

// Child---无参构造函数!

// Parent---执行非静态代码块了1!

// Parent---执行非静态代码块了2!

// Parent---有参构造函数!

// Child---执行非静态代码块了1!

// Child---执行非静态代码块了2!

// Child---有参构造函数!

说明:创建多个子类,但父类静态代码块只执行一次。

case 4:

Child.staticChildMethod(4);

break;

// Parent---执行静态代码块了1!

// Parent---执行静态代码块了2!

// Child---执行静态代码块了1!

// Child---执行静态代码块了2!

// Child---静态方法/staticChildNum=4

说明:静态方法只可以调用静态变量。

case 5:

Parent.staticParentMethod(5);

break;

// Parent---执行静态代码块了1!

// Parent---执行静态代码块了2!

// Parent---静态方法/staticParentNum=5

说明:静态方法可通过 父类名.静态方法() 调用。

case 6:

System.out.println("父类的静态变量值staticParentNum="+Parent.staticParentNum);

break;

// Parent---执行静态代码块了1!

// Parent---执行静态代码块了2!

// 父类的静态变量值staticParentNum=0

说明:调用静态变量时,静态代码块会执行。

case 7:

System.out.println("子类的静态变量值staticChildNum="+Child.staticChildNum);

break;

// Parent---执行静态代码块了1!

// Parent---执行静态代码块了2!

// Child---执行静态代码块了1!

// Child---执行静态代码块了2!

// 子类的静态变量值staticChildNum=0

说明:调用子类静态变量,父类静态代码块和子类静态代码块会被执行。

case 8:

System.out.println("父类的静态变量值staticParentNum="+Parent.staticParentNum);

System.out.println("子类的静态变量值staticChildNum="+Child.staticChildNum);

break;

// Parent---执行静态代码块了1!

// Parent---执行静态代码块了2!

// 父类的静态变量值staticParentNum=0

// Child---执行静态代码块了1!

// Child---执行静态代码块了2!

// 子类的静态变量值staticChildNum=0

case 9:

Child f= new Child();

f.ParentMethod(3);

break;

// Parent---执行静态代码块了1!

// Parent---执行静态代码块了2!

// Child---执行静态代码块了1!

// Child---执行静态代码块了2!

// Parent---执行非静态代码块了1!

// Parent---执行非静态代码块了2!

// Parent---无参构造函数!

// Child---执行非静态代码块了1!

// Child---执行非静态代码块了2!

// Child---无参构造函数!

// Parent---非静态方法/parentNum=3

说明:创建子类,用子类调用父类方法,非静态方法可以调用静态变量。

default:

break;

}

}

}

总结

Java代码初始化顺序

由 static 关键字修饰的(如:类变量(静态变量)、静态代码块)将在类被初始化创建实例对象之前被初始化,而且是按顺序从上到下依次被执行。静态(类变量、静态代码块)属于类本身,不依赖于类的实例。

没有 static 关键字修饰的(如:实例变量(非静态变量)、非静态代码块)初始化实际上是会被提取到类的构造器中被执行的,但是会比类构造器中的代码块优先执行到,非静态(实例变量、非静态代码块)的地位是相等的,它们将按顺序被执行。

类变量(静态变量)、实例变量(非静态变量)、静态代码块、非静态代码块的初始化时机

由 static 关键字修饰的(如:类变量[静态变量]、静态代码块)将在类被初始化创建实例对象之前被初始化,而且是按顺序从上到下依次被执行;

没有 static 关键字修饰的(如:实例变量[非静态变量]、非静态代码块)初始化实际上是会被提取到类的构造器中被执行的,但是会比类构造器中的 代码块优先执行到,其也是按顺序从上到下依次被执行。

容易混淆的一个知识点

静态方法只允许直接访问静态成员,而实例方法中可以访问静态成员和实例成员,原因是类还没有实例化,所实例成员也没有被创建,静态方法中因此也不能用this。

欢迎关注公众号交流!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/542656.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql 包含的那些文件

*.frm是描述了表的结构 *.MYD保存了表的数据记录 *.MYI则是表的索引 ibd是MySQL数据文件、索引文件,无法直接读取。 转载于:https://www.cnblogs.com/07byte/p/5823667.html

math 计算float_Java Math类静态float min(float f1,float f2)与示例

math 计算float数学类静态浮点数min(float f1,float f2) (Math Class static float min(float f1 , float f2) ) This method is available in java.lang package. 此方法在java.lang包中可用。 This method is used to return the minimum one of both the given a…

vector 不初始化时什么状态_Vue原理解析(三):初始化时created之前做了什么?...

让我们继续this._init()的初始化之旅,接下来又会执行这样的三个初始化方法:initInjections(vm) initState(vm) initProvide(vm)5. initInjections(vm): 主要作用是初始化inject,可以访问到对应的依赖。inject和provide这里需要简单的提一下&a…

switch 字符串 java_JDK7新特性switch支持字符串

在JDK7中,switch语句的判断条件增加了对字符串类型的支持。由于字符串的操作在编程中使用频繁,这个新特性的出现为Java编程带来了便利。接下来通过一个案例演示一下在switch语句中使用字符串进行匹配。public class Example {public static void main(String[] args) {String w…

cisco packet tracer路由器配置_【干货】思科交换机路由器怎么配置密码?

今天带大家看看如何在思科的交换机路由器当中配置安全特性,也就是密码的配置方式。在学习配置之前,我们先回顾一下密码相关知识。密码学是研究信息系统安全保密的科学。人类有记载的通信密码始于公元前400年,古希腊人是置换密码学的发明者。密…

perl 哈希数组的哈希_使用哈希检查两个数组是否相似

perl 哈希数组的哈希Prerequisite: Hashing data structure 先决条件: 哈希数据结构 Problem statement: 问题陈述: Check whether two arrays are similar or not using the hash table. The arrays are of the same size. 使用哈希表检查两个数组是否…

codevs3872 邮递员送信(SPFA)

邮递员送信 时间限制: 1 Sec 内存限制: 64 MB提交: 10 解决: 5[提交][状态][讨论版] 题目描述 有一个邮递员要送东西,邮局在节点1.他总共要送N-1样东西,其目的地分别是2~N。由于这个城市的交通比较繁忙,因此所有的道路都是单行的&#xff0…

java上传csv文件上传_java处理csv文件上传示例详解

前言:示例只是做了一个最最基础的上传csv的示例,如果要引用到代码中去,还需要根据自己的业务自行添加一些逻辑处理。readcsvutil工具类package com.hanfengyeqiao.gjb.utils;import java.io.*;import java.util.*;/*** csv工具类*/public cla…

360更新补丁一直提示正在安装_远程利用POC公布|CVE20200796:微软发布SMBv3协议“蠕虫级”漏洞补丁通告...

更多全球网络安全资讯尽在邑安全www.eansec.com0x00 事件描述2020年3月11日,360CERT监测到有海外厂家发布安全规则通告,通告中描述了一处微软SMBv3协议的内存破坏漏洞,编号CVE-2020-0796,并表示该漏洞无需授权验证即可被远程利用&…

字符串的回文子序列个数_计算给定字符串中回文子序列的数量

字符串的回文子序列个数Problem statement: 问题陈述: Given a string you have to count the total number of palindromic subsequences in the giving string and print the value. 给定一个字符串,您必须计算给定字符串中回文子序列的总数并打印该值…

Linux-破解rhel7-root密码

破解7的密码1.linux16 rd.break2.mount -o remount,rw /sysroot3.chroot /sysroot4.passwd5.touch /.autorelabelexitexit7版本grub菜单加密1.grub2-mkpasswd-pbkdf22.vi /etc/grub.d/40_customset superusers"root"password_pbkdf2 root grub.pbkdf2.sha512.10000.…

适配接口 java_【Java 设计模式】接口型模式--Adapter(适配器)模式

简介:【Java设计模式】接口型模式–Adapter(适配器)模式Adapter模式的宗旨就是:向客户提供接口,并使用现有的类所提供的服务,以满足客户的需求。 或者说,现在有classA的方法满足客户的部分要求,将另一部分需…

deepinu盘制作工具_u盘启动盘制作工具怎么制作 u盘启动盘制作工具制作方法【详细步骤】...

在电脑城很多技术人员都会使用u盘装系统的方法给用户电脑安装系统,他们是怎么操作的呢?其实很简单,就是通过u盘启动盘来安装系统的。而u盘启动盘是需要用 u盘启动盘制作工具 来制作的。那么问题又来了,u盘启动盘制作工具怎么制作呢?下面就给…

openstack私有云_OpenStack-下一代私有云的未来

openstack私有云The OpenStack project is an open source cloud computing platform for all types of clouds, which aims to be simple to implement, massively scalable, and feature rich. Developers and cloud computing technologists from around the world create t…

outlook2010客户端无法预览及保存word,excel问题

outlook2010客户端遇到的EXCEL预览及保存问题今天遇到了一个这样的问题,outlook2010打开以后其他的excel都可以打开预览及保存,这个excel无法预览既保存,经查是outlook2010预览及打开的缓存有限制,超过后就无法预览了,…

python自动化框架pytest pdf_Python 自动化测试框架 unittest 和 pytest 对比

一、用例编写规则1.unittest提供了test cases、test suites、test fixtures、test runner相关的类,让测试更加明确、方便、可控。使用unittest编写用例,必须遵守以下规则:(1)测试文件必须先import unittest(2)测试类必须继承unittest.TestCase(3)测试方法必须以“test_”开头(4…

freemarker的测试结果框架_java必背综合知识点总结(框架篇)

框架篇一、Struts1的运行原理在启动时通过前端总控制器ActionServlet加载struts-config.xml并进行解析,当用户在jsp页面发送请求被struts1的核心控制器ActionServlet接收,ActionServlet在用户请求时将请求参数放到对应的ActionForm对象中的成员变量中&am…

Java SecurityManager checkPackageDefinition()方法与示例

SecurityManager类的checkPackageDefinition()方法 (SecurityManager Class checkPackageDefinition() method) checkPackageDefinition() method is available in java.lang package. checkPackageDefinition()方法在java.lang包中可用。 We call getProperty("package.d…

java容器详解_详解Java 容器(第①篇)——概览

![](http://img.blog.itpub.net/blog/2020/04/02/9d89d3008962c127.png?x-oss-processstyle/bb)容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 Map 存储着键值对(两个对象)的映射表。# 一、Collection![](https://upload-images…

python图形界面库哪个好_8个必备的Python GUI库

Python GUI 库有很多,下面给大家罗列常用的几种 GUI库。下面介绍的这些GUI框架,能满足大部分开发人员的需要,你可以根据自己的需求,选择合适的GUI库。1. wxPython wxPython 是一个跨平台的 GUI 工具集,是 Python 语言的…