本篇文章主要分为两个模块进行介绍:1.final,staic,static final之间的异同;2. static 模块;3.嵌套类的概念

1.final,staic,static final之间的异同:

(1)final

final可以修饰属性,方法,类,局部变量(静态变量、实例变量和局部变量);

其中,final修饰的属性表明是个常量,它的初始化可以在编译期,也可以在运行期,初始化后不能被改变;

final修饰的属性跟具体对象有关,在运行期初始化的final属性,不同对象可以有不同的值;

final修饰的方法不能被子类方法覆盖,但可以被继承;

private不能被子类方法覆盖,private类型的方法默认是final类型的

final修饰的类不能被继承,没有子类,final类中的方法默认是final的

final不能用于修饰构造方法;

另外,对于基本类型数据,final会将值变为一个常数(创建后不能被修改);但是对于对象句柄(亦可称作引用或者指针),final会将句柄变为一个常数(进行声明时,必须将句柄初始化到一个具体的对象。而且不能再将句柄指向另一个对象。但是,对象的本身是可以修改的。这一限制也适用于数组,数组也属于对象,数组本身也是可以修改的。方法参数中的final句柄,意味着在该方法内部,我们不能改变参数句柄指向的实际东西,也就是说在方法内部不能给形参句柄再另外赋值)。

(2)static

static表示“全局”或者“静态”的意思,可以用来修饰:属性,方法,代码段,内部类(静态内部类或嵌套内部类),static不可以修饰局部变量。
其中,static修饰的属性的初始化在编译期(类加载的时候),初始化后能改变,并且每个对象都只有一个值,主要强调它们只有一个。

static修饰的属性、方法、代码段跟该类的具体对象无关,不创建对象也能调用static修饰的属性、方法等,

static和“this、super”势不两立,因为this、super正好跟具体对象有关。

也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。

用public修饰的static属性和方法本质是全局变量和全局方法,当声明它类的对象时,不生成static变量的副本,而是类的所有实例共享同一个static变量。
 其中:
- 类成员变量
  - 静态变量(类变量): static修饰
  - 实例变量  : 无static修饰
  - 局部变量 :(方法内部声明)

(3)static final(等价于final staic,但是一般习惯staic在前)

static修饰的属性强调它们只有一个,final修饰的属性表明是一个常数(创建后不能被修改)。static final修饰的属性表示一旦给值,就不可修改,并且可以通过类名访问。static final也可以修饰方法,表示该方法不能重写,可以在不new对象的情况下调用

2.static{}代码块与普通{}代码块的区别

在类中,可以将某一块代码声明为静态的,这样的程序块叫静态初始化段。静态代码块的一般形式如下:

  1. //静态代码块
  2. static {
  3. 语句序列
  4. }
  5.  
  6. //普通代码
  7. {
  8. 语句序列
  9. }

其中,静态代码块只能定义在类里面,它独立于任何方法,不能定义在方法里面。

静态代码块里面的变量都是局部变量,只在本块内有效。

静态代码块会在类被加载时自动执行,而无论加载者是JVM还是其他的类。

一个类中允许定义多个静态代码块,执行的顺序根据定义的顺序进行。

静态方法只能访问静态成员,实例方法可以访问静态和实例成员。之所以不允许静态方法访问实例成员变量,是因为实例成员变量是属于某个对象的,而静态方法在执行时,并不一定存在对象。同样,因为实例方法可以访问实例成员变量,如果允许静态方法调用实例方法,将间接地允许它使用实例成员变量,所以它也不能调用实例方法。基于同样的道理,静态方法中也不能使用关键字this。main()方法是一个典型的静态方法,它同样遵循一般静态方法的规则,所以它可以由系统在创建对象之前就调用。

例子1:

  1. public class staticBlock{
  2. //定义一个普通的main()方法
  3. public static void main(String args[]){
  4. System.out.println("This is main method.");
  5. }
  6. //定义一个静态代码块
  7. static{
  8. System.out.println("This is static block.");
  9. int stVar = 0; //这是一个局部变量,只在本块内有效
  10. }
  11. }

运行结果:

  1. This is static block.
  2. This is main method. 

从以上输出结果中可以看出,静态代码块甚至在main方法之前就被执行。在main()方法中可以完成的任务在静态代码块中都可以完成。但是二者在执行上仍然有一些区别。

例子2:

  1. public class staticBlock{
  2. static int stMember = 100; //定义静态成员变量
  3. public static void main(String args[]){
  4. System.out.println("This is main method.");
  5. }
  6. //第一个静态代码块
  7. static{
  8. System.out.println("This is first static block.");
  9. stMember = 200; //访问静态成员变量
  10. staticBlock oa = new staticBlock(); //创建对象
  11. System.out.println("stMember = " + oa.stMember);
  12. statFun(); //调用静态方法
  13. }
  14. //定义一个静态方法
  15. static void statFun(){
  16. System.out.println("This is a static method.");
  17. }
  18. //第二个静态代码块
  19. static{
  20. System.out.println("This is second static block.");
  21. }
  22. }

运行结果如下:

  1. This is first static block.
  2. stMember = 200
  3. This is a static method.
  4. This is second static block.
  5. This is main method.

静态代码块与普通代码块的差异如下:

相同点:都是在JVM加载类时且在构造方法执行之前执行,在类中都可以定义多个,

    一般在代码块中对一些static变量进行赋值。

不同点:静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)。

    静态代码块只在第一次new执行一次,之后不再执行,而非静态代码块在每new

    一次就执行一次。非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。

例子:

  1. //普通类
  2. public class PuTong {
  3. public PuTong(){
  4. System.out.print("默认构造方法!-->");
  5. }
  6.  
  7. //非静态代码块
  8. {
  9. System.out.print("非静态代码块!-->");
  10. }
  11.  
  12. //静态代码块
  13. static{
  14. System.out.print("静态代码块!-->");
  15. }
  16.  
  17. public static void test(){
  18. {
  19. System.out.println("普通方法中的代码块!");
  20. }
  21. }
  22. }
  23.  
  24. //测试类
  25. publicclass TestClass {
  26.  
  27. /**
  28. * 区别两次new静态与非静态代码块执行情况
  29. */
  30. public static void main(String[] args) {
  31. PuTong c1 = new PuTong();
  32. c1.test();
  33.  
  34. PuTong c2 = new PuTong();
  35. c2.test();
  36. }
  37. }

/*
运行输出结果是:
静态代码块!-->非静态代码块!-->默认构造方法!-->普通方法中的代码块!
非静态代码块!-->默认构造方法!-->普通方法中的代码块!
*/

一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来调用的时候,需要使用静态方法,这种代码是被动执行的.

两者的区别就是:静态代码块是自动执行的;

静态方法是被调用的时候才执行的.

作用:静态代码块可用来初始化一些项目最常用的变量或对象;静态方法可用作不创建对象也可能需要执行的代码.

 

3.嵌套类概念

可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型:静态嵌套类和非静态嵌套类。静态嵌套类使用很少,最重要的是非静态嵌套类,也即是被称作为内部类(inner)。嵌套类从JDK1.1开始引入。其中inner类又可分为三种:
  其一、在一个类(外部类)中直接定义的内部类;
  其二、在一个方法(外部类的方法)中定义的内部类;
  其三、匿名内部类。

(1)静态嵌套类

  1. public class StaticTest {
  2. private static String name = "javaJohn"; 
  3.   private String id = "X001";
  4.   static class Person{
  5.     private String address = "swjtu,chenDu,China";
  6.     public String mail = "josserchai@yahoo.com";//内部类公有成员
  7.     public void display(){
  8.       //System.out.println(id);//不能直接访问外部类的非静态成员
  9.       System.out.println(name);//只能直接访问外部类的静态成员
  10.       System.out.println("Inner "+address);//访问本内部类成员。
  11.     }
  12.   }
  13.  
  14.   public void printInfo(){
  15.     Person person = new Person();
  16.     person.display();
  17.     //System.out.println(mail);//不可访问
  18.     //System.out.println(address);//不可访问
  19.     System.out.println(person.address);//可以访问内部类的私有成员
  20.     System.out.println(person.mail);//可以访问内部类的公有成员
  21.  
  22.   }
  23.   public static void main(String[] args) {
  24.   StaticTest staticTest = new StaticTest();
  25.   staticTest.printInfo();
  26. }
  27. }

在静态嵌套类内部,不能访问外部类的非静态成员,这是由Java语法中"静态方法不能直接访问非静态成员"所限定。若想访问外部类的变量,必须通过其它方法解决,由于这个原因,静态嵌套类使用很少。注意,外部类访问内部类的的成员有些特别,不能直接访问,但可以通过内部类来访问,这是因为静态嵌套内的所有成员和方法默认为静态的了。同时注意,内部静态类Person只在类StaticTest 范围内可见,若在其它类中引用或初始化,均是错误的。

(2)外部内中的内部类

  1. public class Outer {
  2.   int outer_x = 100;
  3.     class Inner{
  4.       public int y = 10;
  5.       private int z = 9;
  6.       int m = 5;
  7.       public void display(){
  8.         System.out.println("display outer_x:"+ outer_x);
  9.       }
  10.       private void display2(){
  11.         System.out.println("display outer_x:"+ outer_x);
  12.       }
  13.     }
  14.     void test(){
  15.       Inner inner = new Inner();
  16.       inner.display();
  17.       inner.display2();
  18.       //System.out.println("Inner y:" + y);//不能访问内部内变量
  19.       System.out.println("Inner y:" + inner.y);//可以访问
  20.       System.out.println("Inner z:" + inner.z);//可以访问
  21.       System.out.println("Inner m:" + inner.m);//可以访问
  22.       InnerTwo innerTwo = new InnerTwo();
  23.       innerTwo.show();
  24.     }
  25.     class InnerTwo{
  26.       Inner innerx = new Inner();
  27.       public void show(){
  28.         //System.out.println(y);//不可访问Innter的y成员
  29.         //System.out.println(Inner.y);//不可直接访问Inner的任何成员和方法
  30.         innerx.display();//可以访问
  31.         innerx.display2();//可以访问
  32.         System.out.println(innerx.y);//可以访问
  33.         System.out.println(innerx.z);//可以访问
  34.         System.out.println(innerx.m);//可以访问
  35.       }
  36.     }
  37.     public static void main(String args[]){
  38.       Outer outer = new Outer();
  39.       outer.test();
  40.     }
  41.   }

以上代码需要说明有,对于内部类,通常在定义类的class关键字前不加public 或 private等限制符,若加了没有任何影响,同时好像这些限定符对内部类的变量和方法也没有影响(?)。另外,就是要注意,内部类Inner及InnterTwo只在类Outer的作用域内是可知的,如果类Outer外的任何代码尝试初始化类Inner或使用它,编译就不会通过。同时,内部类的变量成员只在内部内内部可见,若外部类或同层次的内部类需要访问,需采用示例程序中的方法,不可直接访问内部类的变量。

3.在代码块的作用域内定义内部类。

  1. public class Outer {
  2.  
  3. private String outerName = "This is Outer Name";
  4.  
  5. public void test() {
  6.  
  7. for(int i=0;i<3;i++) {
  8. class Inner {
  9. public void display() {
  10. System.out.println(outerName);
  11. }
  12. }
  13. Inner inner = new Inner();
  14. inner.display();
  15. }
  16. }
  17. }

在上面的代码中,只能定义成class inner,不能定义成public class inner,因为此时是作为方法中的变量定义的,不是作为类的成员变量。

参考链接:

https://blog.csdn.net/qq_40665031/article/details/78440084

https://blog.csdn.net/hust_yfang/article/details/79585696

https://www.cnblogs.com/EasonJim/p/7841990.html

https://blog.csdn.net/leixiongbo/article/details/52161936

https://blog.csdn.net/WelcomeSpring/article/details/79430546

 

final与 static的区别;static代码块以及嵌套类介绍的更多相关文章

  1. 13_java之final|static|包|匿名对象|代码块|内部类

    01final关键字概念 * A: 概述 继承的出现提高了代码的复用性,并方便开发.但随之也有问题,有些类在描述完之后,不想被继承, 或者有些类中的部分方法功能是固定的,不想让子类重写.可是当子类继承 ...

  2. Java基础进阶:继承重点摘要,继承详解,方法重写注意事项,方法重载与重写的区别,抽象类,代码块, 附重难点,代码实现源码,课堂笔记,课后扩展及答案

    继承重点摘要 *继承的特点: 子类在初始化之前,一定要先完成父类数据的初始化 子类在初始化之前,一定要先访问父类构造,完成父类数据的初始化 系统在每一个构造方法中默认隐藏了一句super(); 如果我 ...

  3. 阶段1 语言基础+高级_1-3-Java语言高级_1-常用API_1_第6节 static静态_15_静态代码块

    static的特殊用法, 静态代码块 加上构造方法,做测试 又创建一个对象 静态代码块 只执行一次 后续在学习jdbc的时候,静态代码块很有用途.

  4. Python基础学习Day6 is id == 区别,代码块,小数据池 ---->>编码

    一.代码块 Python程序是由代码块构造的.块是一个python程序的文本,他是作为一个单元执行的. 代码块:一个模块,一个函数,一个类,一个文件等都是一个代码块. 而作为交互方式输入的每个命令都是 ...

  5. static{}静态代码块与{}普通代码块之间的区别

    先看一个例子: //class A package com.my.test; class A { static { System.out.println("A1:父类静态代码区域" ...

  6. 5.1JAVA基础复习——JAVA中的静态代码块、构造代码块、构造函数、局部代码块区别

    构造代码块: 在类中定义可以给所有对象进行初始化.局部代码块: 在方法中定义属性的生命周期.静态代码块: 在类中定义用于给类调用时属性的初始化 构造函数与构造代码块的区别: 构造函数是给对应的对象进行 ...

  7. java静态类、静态方法、静态代码块,静态变量及实例方法,实例变量初始化顺序及内存管理,机制

    1.当一个类被第一次使用时,它需要被类加载器加载,而加载过程涉及以下两点: (1)在加载一个类时,如果它的父类还未被加载,那么其父类必须先被加载: (2)当类加载到内存之后,按照在代码中的出现顺序执行 ...

  8. final、static、代码块、静态代码块、内部类、代码执行顺序

    final final域使得确保初始化安全性(initialization safety)成为可能,初始化安全性让不可变形对象不需要同步就能自由地被访问和共享 作用在类上               ...

  9. [Day13]static、final、匿名对象、内部类、包、修饰符、代码块

    1.final-最终 (1)final的特点 final修饰类不可以被继承,但是可以继承其他类 final修饰的方法不可以被覆盖,但父类中没有final修饰方法,子类覆盖后可以加final final ...

随机推荐

  1. MAMP "403 Forbidden You don't have permission to access / on this server."

    2015年01月22日 17:27:31 阅读数:3488 用MAMP搭建本地服务器的时候,设置好ip和端口等属性之后,浏览器访问,报 403错误: Forbidden You don't have ...

  2. Roslyn NameSyntax 的 ToString 和 ToFullString 的区别

    本文告诉大家经常使用的 NameSyntax 拿到值的 ToString 和 ToFullString 方法的区别 从代码可以看到 NameSyntax 的 ToString 和 ToFullStri ...

  3. JavaScript DOM查询,原生js实现元素子节点的获取

    在网页网页开发中,经常会需要获取某个网页元素的子元素,然后对其进行事件绑定.或样式修改等行为.这些操作对于jquery来说很容易,但是对于原生js会稍微麻烦一些,这里将介绍四种方法获取元素的子元素(本 ...

  4. javascript基础的一些总结

    一 闭包 各种专业文献上的"闭包"(closure)定义非常抽象,很难看懂.我的理解是,闭包就是能够读取其他函数内部变量的函数. 由于在Javascript语言中,只有函数内部的子 ...

  5. 慕课网electron写音乐播放器教程,代码跟随教程变动(十)

    添加播放状态,首先是歌曲名称和时间 在index.html中添加 <div class="container fixed-bottom bg-white pb-4"> ...

  6. java环境所遇问题

    在javac能运行通过并且生成了.class文件但是java文件在运行时通不过出现上面图片情况,试了一上午发现我的和别人好像不一样,下面展示我的情况, 之前用户变量那里新建了一个classpath,不 ...

  7. while Ture怎么退出全部

    while True: #这是一个死循环 如果想要quit出去只能一层一层的退出 比如如果在第三层输入quit会回到第二层 那么有什么方法能够在第三层就退出全部? print("level1 ...

  8. Linux中安装软件和各种常用命令

    1.Centos7中安装mysql5.7的链接:http://blog.csdn.net/fanpeizhong/article/details/73557202 2.修改mysql默认密码的链接:h ...

  9. 7.13 Python基础语法

    Python基础语法 编码: 默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串. 当然你也可以为源码文件指定不同的编码 python2.7中有两个函数 ...

  10. 【题解】NOIP2017逛公园(DP)

    [题解]NOIP2017逛公园(DP) 第一次交挂了27分...我是不是必将惨败了... 考虑这样一种做法,设\(d_i\)表示从该节点到n​节点的最短路径,\(dp(i,k)\)表示从\(i\)节点 ...