一文讲清楚static关键字
static能修饰的地方
静态变量
- 静态变量: 又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,可以直接通过类名来访问它;静态变量在内存中只存在一份。
- 实例变量: 每创建一个实例就会产生一个实例变量,它与该实例同生共死。
静态方法
静态方法在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法(abstract)。
只能访问所属类的静态字段和静态方法,方法中不能有 this 和 super 关键字。
静态语句块
- 静态语句块在类初始化时运行一次。
静态内部类
非静态内部类依赖于外部类的实例,而静态内部类不需要。
静态内部类不能访问外部类的非静态的变量和方法。
静态导包
- 在使用静态变量和方法时不用再指明 ClassName,从而简化代码,但可读性大大降低。
初始化顺序
静态属性,静态代码块。
普通属性,普通代码块。
构造方法。
public class InitOrder {
// 静态属性
private static String staticField = getStaticField();
// 静态代码块
static {
System.out.println(staticField);
System.out.println("静态代码块初始化");
}
// 普通属性
private String field = getField();
// 普通代码块
{
System.out.println(field);
System.out.println("普通代码块初始化");
}
// 构造方法
public InitOrder() {
System.out.println("构造方法初始化");
}
// 静态方法
public static String getStaticField() {
String staticFiled = "静态属性初始化";
return staticFiled;
}
// 普通方法
public String getField() {
String filed = "普通属性初始化";
return filed;
}
public static void main(String[] argc) {
new InitOrder();
}
/**
* 静态属性初始化
* 静态代码块初始化
* 普通属性初始化
* 普通代码块初始化
* 构造方法初始化
*/
}
静态方法和变量能否被继承
先说结论:能
父类A:
public class A {
public static String staticStr = "A静态属性";
public String nonStaticStr = "A非静态属性";
public static void staticMethod(){
System.out.println("A静态方法");
}
public void nonStaticMethod(){
System.out.println("A非静态方法");
}
}
子类B:
public class B extends A{
public static String staticStr = "B改写后的静态属性";
public String nonStaticStr = "B改写后的非静态属性";
public static void staticMethod(){
System.out.println("B改写后的静态方法");
}
@Override
public void nonStaticMethod() {
System.out.println("B改写后的非静态方法");
}
}
子类C:
public class C extends A{
}
测试:
public class Demo {
public static void main(String[] args) {
C c = new C();//C的引用指向C的对象
System.out.println(c.nonStaticStr);//A非静态属性
System.out.println(c.staticStr);//A静态属性
c.nonStaticMethod();//A非静态方法
c.staticMethod();//A静态方法
//推出静态属性和静态方法可以被继承
System.out.println("-------------------------------");
A c1 = new C();//A的引用指向C的对象
System.out.println(c1.nonStaticStr);//A非静态属性
System.out.println(c1.staticStr);//A静态属性
c1.nonStaticMethod();//A非静态方法
c1.staticMethod();//A静态方法
//推出静态属性和静态方法可以被继承
System.out.println("-------------------------------");
B b = new B();//B的引用指向B的对象
System.out.println(b.nonStaticStr);//B改写后的非静态属性
System.out.println(b.staticStr);//B改写后的静态属性
b.nonStaticMethod();//B改写后的非静态方法
b.staticMethod();//B改写后的静态方法
System.out.println("-------------------------------");
A b1 = new B();//A的引用指向B的对象
System.out.println(b1.nonStaticStr);//A非静态属性
System.out.println(b1.staticStr);//A静态属性
b1.nonStaticMethod();//B改写后的非静态方法
b1.staticMethod();//A静态方法
//结果都是父类的静态方法,说明静态方法不可以被重写,不能实现多态
}
}
注意
静态变量尤其要注意并发问题。因为静态变量在Java中是类级别的变量,它们被所有类的实例共享。由于静态变量是共享资源,当多个线程同时访问和修改静态变量时,就会引发并发问题。
总结
子类会继承父类的静态方法和静态变量,但是无法对静态方法进行重写
子类中可以直接调用父类的静态方法和静态变量
子类可以直接修改(如果父类中没有将静态变量设为private)静态变量,但这是子类自己的静态变量。
子类可以拥有和父类同名的,同参数的静态方法,但是这并不是对父类静态方法的重写,是子类自己的静态方法,子类只是把父类的静态方法隐藏了。
当父类的引用指向子类时,使用对象调用静态方法或者静态变量,是调用的父类中的静态方法或者变量(这比较好理解,因为静态方法或变量是属于类的,而引用指向的是一个对象,对象中并不会包含静态的方法和属性)。也就是说,失去了多态。
当子类的引用指向子类时,使用对象调用静态方法或者静态变量,就是调用的子类中自己的的静态方法或者变量了。
关于作者
来自一线程序员Seven的探索与实践,持续学习迭代中~
本文已收录于我的个人博客:https://www.seven97.top
公众号:seven97,欢迎关注~
一文讲清楚static关键字的更多相关文章
- 理解Java中的final和static关键字
回顾这两个关键字前,先考虑一个问题: Static变量存储在JVM中的位置,或者说static变量是如何被加载的? JVM会把类的静态方法和静态变量在类加载的过程中读入方法区(Method Area) ...
- static关键字的用法和main函数
一.static关键字:静态的,它可以修饰成员变量和成员方法 1.修饰成员变量的情况,当类所属对象中存在共享数据时,我们就可以把数据对应的属性定义为静态的,这里的共享数据是对象数据相同,而不是拥有相同 ...
- java中构造方法和this,static关键字
构造方法: 构造方法是一种特殊的方法,用于创建该类的对象,对对象的数据进行初始化 格式如下: [修饰符] 类名(形参列表){ 方法体 } 特点 A:方法名和类名相同 B:没有返回值类型,连void都 ...
- C++从静态对象的初始化顺序理解static关键字
问题 首先考虑一个全局变量的初始化顺序问题 在头文件1中: extern int b; ; 在头文件2中: extern int a; ; 源文件中包含了头文件1和头文件2,这种情况下a和b可能的值是 ...
- static关键字真能提高Bean的优先级吗?答:真能
生命太短暂,不要去做一些根本没有人想要的东西.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习 ...
- 浅谈Static关键字
1.使用static关键字声明的属性为全局属性 未使用static关键字指定city之前,如果需要将Tom,Jack,Mary三人的城市均改成Beijing,需要再次声明三次对象的city为Beiji ...
- (转)Java中的static关键字解析
转载: http://www.cnblogs.com/dolphin0520/p/3799052.html 一.static关键字的用途 在<Java编程思想>P86页有这样一段话: &q ...
- PHP的final关键字、static关键字、const关键字
在PHP5中新增加了final关键字,它可以加载类或类中方法前.但不能使用final标识成员属性,虽然final有常量的意思,但在php中定义常量是使用define()函数来完成的. final关键字 ...
- Java Static关键字详解
提起static关键字,相信大家绝对不会陌生,但是,想要完全说明白,猛的一想,发现自己好像又说不太明白... ...比方说,昨天被一个同学问起的时候... ... 当然,不是所有人都像我一样学艺不精的 ...
- 关于Java中的static关键字
Java中的 static 关键字,确实是一个关键的字(key word),今天就来总结一下它的用法,说说为什么关键. Java中的 static 关键字主要是用来做内存管理的.理解了这句话才能够比较 ...
随机推荐
- Spark Structured Streaming(一)基础
1. 流处理的场景 我们在定义流处理时,会认为它处理的是对无止境的数据集的增量处理.不过对于这个定义来说,很难去与一些实际场景关联起来.在我们讨论流处理的优点与缺点时,先介绍一下流处理的常用场景. 通 ...
- markdown语法支持测试
latex 公式 \(v, w, \nu, \omega\) \[\iiint, \oiiint \] \(\Set{ x | x<\frac 1 2 }\) \(\displaystyle \ ...
- 多个子节点收集日志-主节点上传到HDFS
Master: ---------------------- #MasterAgentMasterAgent.channels = c1MasterAgent.sources = s1MasterAg ...
- 【VMware vSAN】vSAN Data Protection Part 2:配置管理。
上篇文章"vSAN Data Protection Part 1:安装部署."介绍了如何安装及部署 VMware Snapshot Service Appliance 设备,并在 ...
- K210开发板学习笔记-点亮LED灯
1. 介绍 和 51 单片机非常像,实验的2个LED灯都是一头接了 +3.3v 电源,控制 LED灯亮的话需要 K210芯片 对应的管脚提供一个低电平. 管脚: 低电平-LED亮 高电平-LED灭 G ...
- Java核心字符串String进阶
字符串对象 字符串是对象,不是简单数据类型 封装在java.lang包,自动导入 创建字符串对象 常见创建一个字符串对象有下面2个方法 String str=new String("chen ...
- PHP 程序员为什么依然是外包公司的香饽饽?
大家好,我是码农先森. PHP 唯一的爽点就是开发起来「哇真快」这刚好和外包公司的需求相契合,在 Web 领域的芒荒年代 PHP 以王者姿态傲视群雄.如果 PHP 敢说第二,就没有哪门子语言敢称第一, ...
- .NET Core 3.x 基于AspectCore实现AOP,实现事务、缓存拦截器
最近想给我的框架加一种功能,就是比如给一个方法加一个事务的特性Attribute,那这个方法就会启用事务处理.给一个方法加一个缓存特性,那这个方法就会进行缓存.这个也是网上说的面向切面编程AOP. A ...
- Python 阿里云OSS文件上传下载与文件删除及检索示例
阿里云OSS文件上传下载与文件删除及检索示例 实践环境 运行环境: Python 3.5.4 CentOS Linux release 7.4.1708 (Core)/Win10 需要安装以下类库: ...
- 利用路由守卫实现token过期后返回登录界面
const timeX = localStorage.getItem("time");//如果有时间戳存在会判断token是否过期if(timeX!==null){ const t ...