static和final关键字
static关键字
静态变量
- 静态变量:又称做类变量,也就是这个变量属于整个类,而不属于单个实例。类所有的实例共享静态变量,可以直接通过类名来访问它。静态变量在内存中只存在一份,当系统第一次加载类时,系统为静态变量分配内存,直到该类不在使用,内存才会被回收,生命周期几乎等同于该类的生命周期。
- 实例变量:每创建一个实例就会产生一个实例变量,与该实例同生共死。
public class A {
private int x; //实例变量
private static int y; //静态变量
public static void main(String[] args) {
A a = new A();
//实例变量,只能通过实例来访问
System.out.println(a.x); //0
//静态变量属于类本身,所以既可以通过实例也可以通过类本身来访问
System.out.println(a.y); //0
System.out.println(A.y); //0
//更改静态变量和实例变量的值
a.x = 10;
a.y = 5;
A b = new A();
//静态变量只创建一次,被所有实例共享,实例变量仅属于实例本身
System.out.println(b.x); //0
System.out.println(b.y); //5
}
}
静态方法
静态方法:又称做类方法,在类加载的时候就存在了,它不依赖于任何实例,可以通过类名来访问。静态方法必须有实现,不能是抽象方法,只能访问所属类的静态成员和静态方法,不能出现 this 和 super 关键字,因为该方法不依赖任何实例就可以访问,而实例变量或者方法必须先创建实例才能访问。
public class A {
private int x; //实例变量
private static int y; //静态变量
//main方法本身就是静态方法
public static void main(String[] args) {
//int a = x; 报错
int b = y;
System.out.println(b); //0
}
}
静态代码块
静态代码块:仅在类第一次被加载时运行一次的代码块,可用于对静态变量初始化。
public class A {
static {
System.out.println("hello word!");
}
public static void main(String[] args) {
A a = new A();
A b = new A();
}
}
//输出:hello word!
静态内部类
静态内部类:非静态内部类必须依赖外部类的实例,而静态类不需要,直接通过外部类名来创建。静态内部类不能访问外部类的非静态的变量和方法。
public class A {
public class InnerClass{
}
public static class StaticInnerClass {
}
public static void main(String[] args) {
A a = new A();
//非静态内部类的创建,必须依赖外部类的实例
InnerClass innerClass = a.new InnerClass();
//静态内部类的创建
StaticInnerClass staticInnerClass = new A.StaticInnerClass();
}
}
初始化顺序
静态变量声明和静态语句块优先于实例变量声明和普通语句块,静态变量声明和静态语句块的初始化顺序取决于它们在代码中的顺序,最后才是构造函数的初始化。
存在继承情况下的初始化顺序,括号内容的执行顺序取决于在代码的顺序:
- 父类(静态变量声明、静态语句块)
- 子类(静态变量声明、静态语句块)
- 父类(实例变量声明、普通语句块)
- 父类(构造方法)
- 子类(实例变量声明、普通语句块)
- 子类(构造方法)
顺序规则:第一次加载类(还未创建对象)时,从最顶层父类开始执行静态变量声明、静态语句块(执行顺序与代码顺序有关);当真正创建对象时,从最顶层父类开始执行实例变量声明、普通语句块和构造方法(前面两个先执行,执行顺序与代码顺序有关,构造方法最后执行),只有父类成员初始化完毕,才会初始化子类成员。
class Father {
{
System.out.println("father普通代码块");
}
static {
System.out.println("father静态代码块");
}
public Father() {
System.out.println("father构造方法");
}
}
public class Son extends Father{
{
System.out.println("son普通代码块");
}
static {
System.out.println("son静态代码块");
}
public Son() {
System.out.println("som构造方法");
}
public static void main(String[] args) {
new Son();
}
}
/*输出:
father静态代码块
son静态代码块
father普通代码块
father构造方法
son普通代码块
som构造方法
*/
final关键字
数据
声明数据为常量,可以是编译时常量,也可以是在运行时被初始化后不能被改变的常量。
- 对于基本类型,final 使数值不变;
- 对于引用类型,final 使引用不变,也就不能引用其它对象,但是被引用的对象本身是可以修改的。
final int x = 1;
//x = 2; //报错,基本类型不能更改
final A a = new A();
a.c = 1; //正常运行,引用变量不能更改引用对象,但可以更改对象数据
数据可分为成员变量和局部变量,两种都可以加 final。
成员变量
final 修饰的成员变量必须显示赋初始值。
不管是静态变量还是实例变量,在分配内存时,会先分配默认值(0,\u0000,false 或 null)。当执行静态代码块或者静态变量声明时可对静态变量显示赋初始值;当执行普通代码块、实例变量声明或者构造器时可对实例变量显示赋初始值。如果变量没有显式赋初始值,变量初始值使用默认值。而被 final 修饰的成员变量使用默认值将毫无意义,所有规定 final 修饰的成员变量必须显示赋初始值。
public class A{
static {
//此处代码块比声明执行顺序更早,所以A.a还未赋初始值,为0
//A.b由final修饰,必须有初始值,所以此处先查询声明是否赋初始值,再运行,为10
System.out.println(A.a); //0
System.out.println(A.b); //10
}
private static int a = 10;
private static final int b = 10;
private final int c;
//private final int d; //没有赋初始值报错
public A() {
c = 10;
}
public static void main(String[] args) {
new A();
}
}
局部变量
public void test(final int a) {
//a = 5; //报错,不能对final修饰的形参赋值
}
public static void main(String[] args) {
final String str = "hello";
//str = "Java"; //报错,不能再赋值
final double d;
d = 5.6; //正常运行,局部变量没有默认值,必须显示赋初始值
}
方法
被 final 修饰的方法不能被子类重写。private 方法被隐式地指定为 final,如果在子类中定义的方法和父类中的一个 private 方法签名相同,不是重写父类方法,而是定义了一个新的方法。
class B {
public final void f1() {
}
private void f2() {
}
}
public class A extends B {
public void f1() { //报错
}
private void f2() { //正常
}
}
类
被 final 修饰的类不能被继承。
final class B {
}
public class A extends B { //报错
}
static和final关键字的更多相关文章
- Java的static和final关键字的用法
static关键字的用法 static的意思是"'静态的",在java里面可用于修饰属性和方法. static关键字的应用应注意以下几种情形: 1.static作用于某个字段,一个 ...
- static 和 final 关键字 对实例变量赋初始值的影响
static 和 final 关键字 对实例变量赋初始值的影响 最近一直在看<深入理解Java虚拟机>,在看完了对象内存分配.Class文件格式之后,想深扒一下实例变量是如何被赋上初始值的 ...
- JAVA面对对象(三)——Super、static、final关键字
Super 使用super关键字可以直接调用父类中的构造方法.属性.普通方法 super调用父类构造方法的操作,与this调用构造方法一样,语句必须放在子类构造方法的首行 public class P ...
- 【Java_基础】java中static与final关键字的区别
1.static关键字 经static关键字修饰的成员被该类的所有对象所共享,任意一对象对静态变量的修改其它对象都是可见的.通常通过类名来引用static成员.类加载的连接阶段将会为静态成员变量在jv ...
- java中static,super,final关键字辨析
1:static关键字 利:1)对对象的共享数据提供单独的空间存储. 2)修饰的方法可以直接被类名调用 弊:1)生命周期长. 2)访问出现限制(只能访问静态) 它可以有静态方法,静态类,静态变量 2: ...
- 关于static以及final关键字
Static关键字: 可以用来修饰类中的属性.类中的方法.以及具体的某一个类. 1.用于修饰属性: 则表示该属性属于整个类,不论有多少个对象实例,所有的实例共同拥有一个static静态的成员变量.该变 ...
- Java中的static、final关键字
static static 的含义是静态的,是一个静态修饰符,一般来说,被static修饰的有以下几种,类.变量.方法.代码块. static修饰类 Java中普通的类是不允许被声明为静态的,但是有一 ...
- java中的static和final关键字
一:static 1)修饰成员变量: static关键字可以修饰成员变量,它所修饰的成员变量不属于对象的数据结构,而是属于类的变量,通常通过类名来引用static成员. 当创建对象后,成员变量是存储在 ...
- static,final关键字,Object类的tostring方法,equals方法,hashCode方法
1)static关键字 static可以修饰:属性.方法.代码块 静态方法不能访问非静态 属性 或 方法 属性(变量): 成员变量: 静态变量: 通过 类名.静态变量来访问 通过 对象名.静态变量来访 ...
随机推荐
- 免费淘宝IP地址库简介及PHP/C#调用实例
https://yq.aliyun.com/ziliao/25800?spm=a2c4e.11155472.0.0.68027abfcpFb7O 摘要: 本文讲的是免费淘宝IP地址库简介及PHP/C# ...
- H3C 会话层、表示层和应用层
- springmvc url处理映射的三种方式:
一.SpringMVC简介 SpringMVC是一种基于Spring实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,使用了MVC架构模式的思想,将web层进行职责解耦,并管理应用所需对象 ...
- tf.contrib.layers.xavier_initializer
https://blog.csdn.net/yinruiyang94/article/details/78354257xavier_initializer( uniform=True, seed=No ...
- H3C NAT组网和常用术语
- 浅谈集合框架六——集合扩展:Arrays工具类、集合与数组相互转换方式;
最近刚学完集合框架,想把自己的一些学习笔记与想法整理一下,所以本篇博客或许会有一些内容写的不严谨或者不正确,还请大神指出.初学者对于本篇博客只建议作为参考,欢迎留言共同学习. 之前有介绍集合框架的体系 ...
- Pandas库之DataFrame
Pandas库之DataFrame 1 简介 DataFrame是Python中Pandas库中的一种数据结构,它类似excel,是一种二维表. 或许说它可能有点像matlab的矩阵,但是matlab ...
- The Function() Constructor
Functions are usually defined using the function keyword, either in the form of a function definitio ...
- the password has expired
Oracle提示错误消息ORA-28001: the password has expired,是由于Oracle11G的新特性所致, Oracle11G创建用户时缺省密码过期限制是180天(即6个月 ...
- win2d 通过 CanvasActiveLayer 画出透明度和裁剪
本文告诉大家如果在 UWP 的 win2d 通过 CanvasActiveLayer 创建一层,在这里画出的图片有透明度或者裁剪 在 win2d 如果需要对某个元素裁剪,可以使用很多方法,本文只是告诉 ...