final

final域使得确保初始化安全性(initialization safety)成为可能,初始化安全性让不可变形对象不需要同步就能自由地被访问和共享
作用在类上               则为final类,final类不能被继承。一般用于工具类时,同时把工具类构造函数声明为私有,暴露静态共有方法
作用在成员变量上    则视为常量。此时赋值方式有三种:(1)声明时赋值(2)构造函数中赋值(3)代码块中赋值。 即不管哪种方式都要保证在使用该变量之前要确保已经有值。使用该特性,可以强制赋值。final变量因为不可变,所以可以安全的存在于多线程中。
作用在方法上           作用在方法上可以保证该方法不能被重写
作用在参数上           保证在方法体内部参数值不会被再次赋值,一般好的编程习惯应该把参数值视为final,不管有没有显示使用final(重构)

static

static关键字是隶属于类而非对象。这也就意味着不管声明了几个对象,static关键字所修饰的空间只占用一份。改变了之后,所有的引用它的都会发生变化。静态成员变量为所有类的对象共享。不像对象之间的变量是无影响的。所以对于static修饰的成员变量或者静态代码块是在类加载的时候已经装载。这种特性可以做一些初始化的工作而且保证只初始化了一次。
作用在包上 (import static(注意这里不是static import)  com…..ClassName.* 静态导包)这种以后再使用包里面的静态方法或者成员变量时会比较方便。eg:
import static java.lang.Integer.*;
int max_value = MAX_VALUE;
toHexString(max_value);
这样就导入了Integer类下面所有的静态方法和成员变量。在使用的时候就可以省去Integer,直接使用。
作用在类上       修饰类则为静态类。只能作为静态内部类,如果直接修饰类,则不能通过编译。
作用在方法上   修饰方法则为静态方法。静态方法中不能使用非静态变量。因为静态方法中不能确定该方法是否有被初始化。但是非静态方法可以引用静态变量。
作用在变量上   作用在变量上则为静态变量。静态成员变量一般声明为final的。因为隶属于该类所有对象,可更改存在着危险。

代码块

代码块分为普通代码块和构造代码块
普通代码块:在方法或语句中出现的{},用的比较少。执行顺序是按声明顺序执行。eg:
 public static void main(String[] args) {
{
System.out.println("普通代码块-先声明");
}
System.out.println("函数普通");
{
System.out.println("普通代码块-后声明");
}
}
程序输出结果如下:
普通代码块-先声明
函数普通
普通代码块-后声明
构造代码块:直接在类中定义且没有static关键字的代码块,比较常用。执行顺序是在构造函数执行之前执行,每声明一个对象都会执行一次。
 public class CodeBlock {
{
System.out.println("构造代码块-先声明-执行");
}
public CodeBlock(){
System.out.println("构造器执行");
}
{
System.out.println("构造代码块-后声明-执行");
}
public void plainFunc(){
System.out.println("普通方法执行");
}
public static void main(String[] args) {
System.out.println("main方法");
CodeBlock cb1 = new CodeBlock();
cb.plainFunc();
CodeBlock cb2 = new CodeBlock();
}
}
程序输出结果如下:
main方法
构造代码块-先声明-执行
构造代码块-后声明-执行
构造器执行
普通方法执行
构造代码块-先声明-执行
构造代码块-后声明-执行
构造器执行
结论:
执行顺序:main方法->构造代码块->构造函数->普通方法
每实例化一个对象,则执行一次构造代码块

静态代码块

在java中使用static关键字声明的代码块。静态块用于初始化类,为类的属性初始化。每个静态代码块只会执行一次。由于JVM在加载类时会执行静态代码块,所以静态代码块先于主方法执行。
如果类中包含多个静态代码块,那么将按照"先定义的代码先执行,后定义的代码后执行"。
注意:1 静态代码块不能存在于任何方法体内。2 静态代码块不能直接访问静态实例变量和实例方法,需要通过类的实例对象来访问。
 class Code{
{
System.out.println("Code的构造块");
} static{
System.out.println("Code的静态代码块");
} public Code(){
System.out.println("Code的构造方法");
}
}
public class CodeBlock{
{
System.out.println("CodeBlock的构造块");
} static{
System.out.println("CodeBlock的静态代码块");
} public CodeBlock03(){
System.out.println("CodeBlock的构造方法");
} public static void main(String[] args){
System.out.println("CodeBlock的主方法");
new Code();
new Code();
new CodeBlock();
new CodeBlock();
}
}
程序输出如下
CodeBlock的静态代码块
CodeBlock的主方法 //这里还没有加载Code,所以先执行主方法,再执行Code的静态代码块
Code的静态代码块
Code的构造块
Code的构造方法
Code的构造块
Code的构造方法
CodeBlock的构造块
CodeBlock的构造方法

内部类

⒈成员内部类⒉静态内部类⒊局部内部类⒋匿名内部类
定义
将一个类的定义放在另一个类的定义内部,这就是内部类
初见内部类
内部类的创建就和定义的一样,把一个类定义在另一个类的内部
 public class Parcel2 {
class Contents {
private int i = 11;
public int value() { return i; }
}
class Destination {
private String label;
Destination(String whereTo) {
label = whereTo;
}
String readLabel() { return label; }
}
public Destination to(String s) {
return new Destination(s);
}
public Contents contents() {
return new Contents();
}
public void ship(String dest) {
Contents c = contents();
Destination d = to(dest);
System.out.println(d.readLabel());
}
public static void main(String[] args) {
Parcel2 p = new Parcel2();
p.ship("Tasmania");
Parcel2 q = new Parcel2();
// Defining references to inner classes:
Parcel2.Contents c = q.contents();
Parcel2.Destination d = q.to("Borneo");
}
}
这里在类Parcel2中创建了两个内部类Contents和Destination。同时每个内部类对应的创建了一个外部类方法,该方法用来返回一个指向内部类对象的引用。这种方式很常用!如果不提供指向内部类对象引用的函数,需要借助“.new”来创建内部类对象(后面会有用法)。如果想从外部类的非静态方法之外的任意位置创建某个内部类对象,那么必须像上述main()方法那样,具体指明这个对象的类型:OutClassName.InnerClassName(eg:Parcel2.Contents),为什么要这么做呢?
注意:非静态内部类对象有着指向外部类对象的引用。
这可以至少解释两个问题:
1、内部类拥有外部类的所有元素的访问权(因为当生成内部类时内部类自动产生了指向外部类对象的引用,该引用可以访问外部类的所有成员)
2、创建内部类对象时,需要指明对象类型,即:
OutClassName out = new OutClassName();
OutClassName.InnerClassName=out.new InnerClassName(); 
 
使用 .this 和 .new
如果需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟原点和this。如果需要生成内部类对象,可以使用外部类对象后面紧跟原点和this。
外部类引用:
public class DotThis {
void f() { System.out.println("DotThis.f()"); }
public class Inner {
public DotThis outer() {
return DotThis.this;
// A plain "this" would be Inner's "this"
}
}
public Inner inner() { return new Inner(); }
public static void main(String[] args) {
DotThis dt = new DotThis();
DotThis.Inner dti = dt.inner();
dti.outer().f();
}
}
注意:上面代码DotThis.this返回外部类对象引用,如果直接使用this,则是内部类Inner对象引用,不能通过编译。
创建内部类对象:
public class DotNew {
public class Inner {}
public static void main(String[] args) {
DotNew dn = new DotNew();
DotNew.Inner dni = dn.new Inner();
}
}
内部类语法
一、成员内部类(非静态):
1、可以访问外部类所有元素
2、创建对象两种方式:(1)在外部类中声明方法返回内部类对象的引用(2)通过内部类对象后跟原点和new的方式(eg:DotNew dn = new DotNew(); DotNew.Inner dni = dn.new Inner();)
3、成员内部类中不能包含静态数据(成员变量和方法)
二、静态内部类:
1、不能访问外部类的非静态元素和方法。(因为静态内部类没有指向外部类对象的引用,只能直接通过类名来调用)
2、创建方式比较简单
Outer.Inner inner = new Outer.Inner();
inner.func();
3、可以包含静态数据
三、局部内部类
局部内部类就是可以定义在方法体内,比较少用
四、匿名内部类
interface content{
int func();
}
System.out.println(new content(){
@Override
public int func() {
return 1;
}
}.func());
内部类优势:
1、可以访问外部类所有元素
2、隐藏性好,只有本类可操作
3、可以解决C++里面的多继承问题。怎么解决?
我们知道,Java不支持多继承(即一个类同时继承两个或多个类),只支持多重继承(即A继承B,B继承C,那么A间接继承了C),利用Java的内部类机制可以做到多重继承的效果。可以声明多个内部类分别继承相应的类,然后对于外部类来说,就同时拥有了相应内部类的功能。

代码执行顺序

1、父类静态代码块->父类静态成员变量初始化->子类静态代码块->子类静态成员变量初始化->(父类代码块->父类成员变量初始化)(这两个谁先声明谁在前面)->子类代码块->子类成员变量初始化->父类构造函数->子类构造函数->...
  • 静态先于非静态执行
  • 代码块可以当做成员变量来看,对于静态代码块,类加载的时候执行;对于非静态代码块,构造函数之前执行,可以想成是在成员变量初始化的时候执行
  • 父类优先于子类执行(因为子类涉及到对父类的重写等操作,只有父类初始完毕了,子类重写和引用才有意义)

参考文章:

1、《java编程思想》

2、http://www.cnblogs.com/sophine/p/3531282.html

final、static、代码块、静态代码块、内部类、代码执行顺序的更多相关文章

  1. Java父类与子类中静态代码块 实例代码块 静态变量 实例变量 构造函数执行顺序

    实例化子类时,父类与子类中的静态代码块.实例代码块.静态变量.实例变量.构造函数的执行顺序是怎样的? 代码执行的优先级为: firest:静态部分 second:实例化过程 详细顺序为: 1.父类静态 ...

  2. Java 中的 static 使用之静态初始化块

    Java 中可以通过初始化块进行数据赋值.如: 在类的声明中,可以包含多个初始化块,当创建类的实例时,就会依次执行这些代码块.如果使用 static 修饰初始化块,就称为静态初始化块. 需要特别注意: ...

  3. Java类成员变量、普通成员变量、初始化块、构造方法的初始化和执行顺序

    结论:执行的大致顺序如下, (1) 在一个不存在继承的类中:初始化static变量,执行static初始化块-->初始化普通成员变量(如果有赋值语句),执行普通初始化块-->构造方法 (2 ...

  4. 静态(static)代码块、构造代码块、构造函数、父类子类执行顺序

    静态代码块:static修饰的代码块. 在类加载-初始化的时候进行,主要目的是给变量赋予初始值 构造代码块:直接在类中定义且没有加static关键字的代码块称为构造代码块. java会把构造代码块放到 ...

  5. JAVA代码中加了Try...Catch的执行顺序

    public static String getString(){ try { //return "a" + 1/0; return "a"; } catch ...

  6. Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序

    直接上代码: 代码1: public class ConstroctTest { private static ConstroctTest test = new ConstroctTest(); // ...

  7. 【转】java静态代码块和构造方法执行顺序

    先看看下面几个类,然后判断它们的输出public class A { static{System.out.print(1);}public A(){System.out.print(2);}} pub ...

  8. java 子类、父类中静态代码块、字段,非静态代码块、字段以及构造函数的初始化顺序和次数

    一个类中的数据初始化顺序是面试官非常喜欢出的面试题之一,本文用一个实例来介绍java中子类.父类中静态代码块.字段,非静态代码块.字段以及构造函数的执行顺序和次数. 一.包结构

  9. 编写Java程序,观察类启动时静态代码块和main()的执行顺序

    返回本章节 返回作业目录 需求说明: 观察类启动时静态代码块和main()的执行顺序 在Book类中定义静态代码块. 在Book中分别定义一个普通实例方法和静态方法. 在Book类的静态代码块中调用静 ...

  10. static之静态初始化块

    static之静态初始化块 所有的静态初始化块都优先执行,其次才是非静态的初始化块和构造函数,它们的执行顺序是:    父类的静态初始化块    子类的静态初始化块    父类的初始化块    父类的 ...

随机推荐

  1. SSM框架整合项目 :租房管理系统

    使用ssm框架整合,oracle数据库 框架: Spring SpringMVC MyBatis 导包: 1, spring 2, MyBatis 3, mybatis-spring 4, fastj ...

  2. sbt 配置文件

    配置文件名:application.conf, VM options: -Dconfig.file=application.conf 配置文件内容规范: openStrategy{ alive { a ...

  3. Yarn一点小认识

    正文 打开官网http://hadoop.apache.org/docs/r2.6.5/hadoop-yarn/hadoop-yarn-site/YARN.html,将图片拿过来. 我用的是2.6.5 ...

  4. 谦先生的程序员日志之我的hadoop大数据生涯一

    从一个初级程序员到高级程序员的经历 你好!我是谦先生,我是茫茫程序猿中的一猿,平凡又执着. 刚入行的时候说实话,啥都不懂,就懂点皮毛的java,各种被虐狗的感觉.又写js又写css又写后台...慢慢被 ...

  5. Oracle学习笔记之游标详解

    游标 游标存在意义:解决"select *"返回空.多行记录问题,但凡select,就可能多行结果集,也就需要用游标. 游标分4步走:cursor.open.fetch.close ...

  6. php7+apache2.4配置

    因为需要搭建一套discuz的程序,所以就扯到了php. 对于php完全没接触过,然后就百度了下php的容器,看到apache可以.机子上刚好有装,就干脆用它了. 测试环境:win10x64+php7 ...

  7. MySQL比like语句更高效的写法locate position instr find_in_set

    使用内部函数instr,可代替传统的like方式查询,并且速度更快. instr函数,第一个参数是字段,第二个参数是要查询的串,返回串的位置,第一个是1,如果没找到就是0. 例如, select na ...

  8. 主要讲下hack的兼容用法,比较浅,哈哈

    hack是主要来处理IE的兼容,不同的IE,不同的兼容方式 /*   属性前缀法(即类内部Hack):       *color:#000; *号对IE6,IE7都生效   +color:#555; ...

  9. 为什么String类是不可变的?

    为什么String类是不可变的? String类 什么是不可变对象 当满足以下条件时,对象才是不可变的: 对象创建以后其状态就不能修改. 对象的所有域都是final类型的. 对象是正确创建的(在对象的 ...

  10. macOs升级到10.13.1Beta || JAVA升级到最新版之后PhpStorm菜单栏问题

    macOs升级到10.13.1Beta || JAVA升级到最新版之后PhpStorm菜单栏会消失,估计不止出现在PhpStorm,一系列jetbrains的产品可能都会有这个问题,包括eclipis ...