final 关键字

final关键字主要用在三个地方:变量、方法、类。

  1. 对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
  2. 当用final修饰一个类时,表明这个类不能被继承。final类中的所有成员方法都会被隐式地指定为final方法。
  3. 使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升(现在的Java版本已经不需要使用final方法进行这些优化了)。类中所有的private方法都隐式地指定为final。

static 关键字

static 关键字主要有以下四种使用场景:

  1. 修饰成员变量和成员方法: 被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以并且建议通过类名调用。被static 声明的成员变量属于静态成员变量,静态变量 存放在 Java 内存区域的方法区。调用格式:类名.静态变量名 类名.静态方法名()
  2. 静态代码块: 静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)。 该类不管创建多少对象,静态代码块只执行一次.
  3. 静态内部类(static修饰类的话只能修饰内部类): 静态内部类与非静态内部类之间存在一个最大的区别: 非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。没有这个引用就意味着:1. 它的创建是不需要依赖外围类的创建。2. 它不能使用任何外围类的非static成员变量和方法。
  4. 静态导包(用来导入类中的静态资源,1.5之后的新特性): 格式为:import static 这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中静态成员,可以直接使用类中静态成员变量和成员方法。

this 关键字

this关键字用于引用类的当前实例。 例如:

class Manager { Employees[] employees;  void manageEmployees() { int totalEmp = this.employees.length; System.out.println("Total employees: " + totalEmp); this.report(); }  void report() { }}

在上面的示例中,this关键字用于两个地方:

  • this.employees.length:访问类Manager的当前实例的变量。
  • this.report():调用类Manager的当前实例的方法。

此关键字是可选的,这意味着如果上面的示例在不使用此关键字的情况下表现相同。 但是,使用此关键字可能会使代码更易读或易懂。

super 关键字

super关键字用于从子类访问父类的变量和方法。 例如:

public class Super { protected int number;  protected showNumber() { System.out.println("number = " + number); }} public class Sub extends Super { void bar() { super.number = 10; super.showNumber(); }}

在上面的例子中,Sub 类访问父类成员变量 number 并调用其其父类 Super 的 showNumber() 方法。

使用 this 和 super 要注意的问题:

  • 在构造器中使用 super() 调用父类中的其他构造方法时,该语句必须处于构造器的首行,否则编译器会报错。另外,this 调用本类中的其他构造方法时,也要放在首行。
  • this、super不能用在static方法中。

简单解释一下:

被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享。而 this 代表对本类对象的引用,指向本类对象;而 super 代表对父类对象的引用,指向父类对象;所以, this和super是属于对象范畴的东西,而静态方法是属于类范畴的东西

参考

  • https://www.codejava.net/java-core/the-java-language/java-keywords
  • https://blog.csdn.net/u013393958/article/details/79881037

static 关键字详解

static 关键字主要有以下四种使用场景

  1. 修饰成员变量和成员方法
  2. 静态代码块
  3. 修饰类(只能修饰内部类)
  4. 静态导包(用来导入类中的静态资源,1.5之后的新特性)

修饰成员变量和成员方法(常用)

被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以并且建议通过类名调用。被static 声明的成员变量属于静态成员变量,静态变量 存放在 Java 内存区域的方法区。

方法区与 Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。

HotSpot 虚拟机中方法区也常被称为 “永久代”,本质上两者并不等价。仅仅是因为 HotSpot 虚拟机设计团队用永久代来实现方法区而已,这样 HotSpot 虚拟机的垃圾收集器就可以像管理 Java 堆一样管理这部分内存了。但是这并不是一个好主意,因为这样更容易遇到内存溢出问题。

调用格式:

  • 类名.静态变量名
  • 类名.静态方法名()

如果变量或者方法被 private 则代表该属性或者该方法只能在类的内部被访问而不能在类的外部被访问。

测试方法:

public class StaticBean { String name; 静态变量 static int age; public StaticBean(String name) { this.name = name; } 静态方法 static void SayHello() { System.out.println(Hello i am java); } @Override public String toString() { return StaticBean{ + name=' + name + ''' + age + age + '}'; }}public class StaticDemo { public static void main(String[] args) { StaticBean staticBean = new StaticBean(1); StaticBean staticBean2 = new StaticBean(2); StaticBean staticBean3 = new StaticBean(3); StaticBean staticBean4 = new StaticBean(4); StaticBean.age = 33; StaticBean{name='1'age33} StaticBean{name='2'age33} StaticBean{name='3'age33} StaticBean{name='4'age33} System.out.println(staticBean+ +staticBean2+ +staticBean3+ +staticBean4); StaticBean.SayHello();Hello i am java }}

静态代码块

静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块—非静态代码块—构造方法)。 该类不管创建多少对象,静态代码块只执行一次.

静态代码块的格式是

static { 语句体; }

一个类中的静态代码块可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果静态代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。

静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问.

静态内部类

静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。没有这个引用就意味着:

  1. 它的创建是不需要依赖外围类的创建。
  2. 它不能使用任何外围类的非static成员变量和方法。

Example(静态内部类实现单例模式)

public class Singleton {  声明为 private 避免调用默认构造方法创建对象 private Singleton() { }  声明为 private 表明静态内部该类只能在该 Singleton 类中被访问 private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getUniqueInstance() { return SingletonHolder.INSTANCE; }}

当 Singleton 类加载时,静态内部类 SingletonHolder 没有被加载进内存。只有当调用 getUniqueInstance() 方法从而触发 SingletonHolder.INSTANCE 时 SingletonHolder 才会被加载,此时初始化 INSTANCE 实例,并且 JVM 能确保 INSTANCE 只被实例化一次。

这种方式不仅具有延迟初始化的好处,而且由 JVM 提供了对线程安全的支持。

静态导包

格式为:import static

这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中静态成员,可以直接使用类中静态成员变量和成员方法

 Math. --- 将Math中的所有静态资源导入,这时候可以直接使用里面的静态方法,而不用通过类名进行调用 如果只想导入单一某个静态方法,只需要将换成对应的方法名即可 import static java.lang.Math.; 换成import static java.lang.Math.max;具有一样的效果 public class Demo { public static void main(String[] args) {  int max = max(1,2); System.out.println(max); }}

补充内容

静态方法与非静态方法

静态方法属于类本身,非静态方法属于从该类生成的每个对象。 如果您的方法执行的操作不依赖于其类的各个变量和方法,请将其设置为静态(这将使程序的占用空间更小)。 否则,它应该是非静态的。

Example

class Foo { int i; public Foo(int i) {  this.i = i; } public static String method1() { return An example string that doesn't depend on i (an instance variable);  } public int method2() { return this.i + 1; Depends on i }}

你可以像这样调用静态方法:Foo.method1()。 如果您尝试使用这种方法调用 method2 将失败。 但这样可行:Foo bar = new Foo(1);bar.method2();

总结:

  • 在外部调用静态方法时,可以使用”类名.方法名”的方式,也可以使用”对象名.方法名”的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
  • 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制

static{}静态代码块与{}非静态代码块(构造代码块)

相同点: 都是在JVM加载类时且在构造方法执行之前执行,在类中都可以定义多个,定义多个时按定义的顺序执行,一般在代码块中对一些static变量进行赋值。

不同点: 静态代码块在非静态代码块之前执行(静态代码块—非静态代码块—构造方法)。静态代码块只在第一次new执行一次,之后不再执行,而非静态代码块在每new一次就执行一次。 非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。

一般情况下,如果有些代码比如一些项目最常用的变量或对象必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的。如果我们想要设计不需要创建对象就可以调用类中的方法,例如:Arrays类,Character类,String类等,就需要使用静态方法, 两者的区别是 静态代码块是自动执行的而静态方法是被调用的时候才执行的.

Example

public class Test { public Test() { System.out.print(默认构造方法!--); } 非静态代码块 { System.out.print(非静态代码块!--); } 静态代码块 static { System.out.print(静态代码块!--); } public static void test() { System.out.print(静态方法中的内容! --); { System.out.print(静态方法中的代码块!--); } } public static void main(String[] args) { Test test = new Test();  Test.test();静态代码块!--静态方法中的内容! --静态方法中的代码块!-- }

当执行 Test.test(); 时输出:

静态代码块!--静态方法中的内容! --静态方法中的代码块!--

当执行 Test test = new Test(); 时输出:

静态代码块!--非静态代码块!--默认构造方法!--

非静态代码块与构造函数的区别是: 非静态代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。

QQ讨论群组:984370849 706564342 欢迎加入讨论

想要深入学习的同学们可以加入QQ群讨论,有全套资源分享,经验探讨,没错,我们等着你,分享互相的故事!

被final修饰的变量在哪存储_final,static,this,super 关键字总结,一点课堂(多岸学院)...相关推荐

  1. final修饰的变量就是常量?

    概念 什么是常量? 对于这个问题,可能很多人都可以脱口而出 : 用final修饰的变量是常量 ,或者是在编译时期定义好的字符串.(字符串常量) 但是这种说法是不严谨的,因为准确来说 : 常量是用fin ...

  2. final修饰的变量就是常量?final修饰局部变量在栈还是堆还是常量池中?

    概念 常量池 常量池的好处 Class类文件中的常量池 常量池 运行时常量池 包装类常量池对象池 Java中装箱和拆箱 赋值时 方法调用时 方法运算时 参考 概念 什么是常量? 对于这个问题,可能很多 ...

  3. 被final修饰的变量到底能不能被修改

    final:可以修饰类,方法,变量: 对类的修饰:表示类不可以被继承: 对方法修饰:表示该方法不能被子类重写: 对变量修饰:表示该变量不能被修改: 不知道大家有没有遇到一些很奇怪的现象,就是被fina ...

  4. final修饰的变量是引用不能改变还是引用的对象不能改变

    我们都知道final修饰变量时 会变为常量,但是使 用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 下面让我们来看这段代码: [java] view plain copy /* ...

  5. final修饰的变量必须初始化吗?

    final关键字的用法大家应该都知道. 修饰的类不能被继承. 修饰的方法子类可以使用,但是不能进行重写. 修饰的变量只能被赋值一次,引用不可变. 引用不可变的变量,只能被赋值一次.但是如果变量是对象, ...

  6. 关于final修饰的变量赋值的问题

    一.赋值的方式 1.可以定义变量时直接赋值 2.可以在代码块中进行赋值(静态代码块和构造代码块) 3.可以再构造方法中进行赋值. 总结起来,就是要在对象创建之前完成赋值的过程. 二.值能不能改变的问题 ...

  7. final修饰的变量

    被final修饰的实例变量必须显式指定初始值,而且只能在如下3个位置指定初始值. 1.定义final实例变量时指定初始值; 2.在非静态初始化块中为final实例变量指定初始值; 3.在构造器中为fi ...

  8. Java中被final修饰的变量的几种赋值方式

    关于final final 表示"最后的.最终的"含义,变量一旦赋值后,不能被重新赋值.被 final 修饰的实例变量必须显式指定初始值. final 修饰符通常和 static ...

  9. java 中final修饰的变量_java中final修饰符的使用方法

    本文为大家分享了java中final修饰符的使用,供大家参考,具体内容如下 1.final修饰符的用法: final可以修饰变量,被final修饰的变量被赋初始值之后,不能对它重新赋值. final可 ...

最新文章

  1. Winograd,GEMM算法综述(CNN中高效卷积实现)(上)
  2. 【Visual Studio 扩展工具】如何在ComponentOneFlexGrid树中显示RadioButton
  3. 创建oracle dblink权限不足,Oracle-存储过程-创建sequence的时候报权限不足
  4. 多视图几何总结——摄像机模型
  5. MySQL数据库常用命令_常用SQL语句及命令_MySQL常用语句
  6. 布隆过滤器的原理、应用场景和源码分析实现
  7. 【Android 应用开发】Activity 状态保存 OnSaveInstanceState參数解析
  8. Linux下配置OpenLDAP服务记录
  9. 电路板上的插头怎么拔下来_空调插头一直不拔费电吗?实测一周竟然发现了真相!...
  10. sql azure 语法_Azure SQL Server自动故障转移组
  11. 状态规划P4270小奇挖矿2
  12. Ubuntu LVM扩展LV
  13. 主流量化交易的几种策略模型
  14. MySQL 怎么插入10天前的日期_Mysql笔记
  15. 2018蓝桥杯B组国赛第四题 调手表(bfs)
  16. 怎样把PDF格式转换成可编辑的PPT幻灯片?
  17. 一个球从100米高度自由下落,每次落地后反跳回原来的高度的一半,再落下;
  18. 【开源“青女四轴”,DIY小四轴】
  19. numpy序列预处理dna序列_合成生物学快讯2019年第12期:基于DNA的分子数字数据存储...
  20. Matlab:表示 MATLAB 中的日期和时间

热门文章

  1. 皮一皮:为啥年轻人不生孩子?
  2. Nginx如何限流?
  3. 皮一皮:原来骑骆驼要求这么高。。
  4. 每日一皮:听说学琵琶的都很文弱...
  5. 实现单机五子棋,难吗?
  6. 2019年最新10份开源Java精选资料
  7. Java 基础搞定了,还能学点什么?
  8. c 服务器通信和文件传输,服务器、终端和文件传输方法
  9. Android Studio编译问题-Error:Could not find org.jetbrains.trove4j
  10. 卷积神经网络中的各种池化操作