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,欢迎关注~
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容