基础概念

  • 是个修饰符;
  • 修饰变量、常量、方法、代码块;
  • 被修饰的为静态;
  • 方便在没有创建对象的情况下来进行调用(方法/变量);
  • static修饰的成员被所有的对象所共享;
  • static优先于对象存在,因为static的成员随着类的加载就已经存在了;
  • static修饰的数据是共享数据,对象中的存储的是特有数据;

分别举例说明

import lombok.extern.slf4j.Slf4j;
import org.testng.annotations.Test; import java.util.Date; @Slf4j
public class TestStatic {
static Date startDate;
static{
startDate = new Date();
} static String str = "testStr"; static void test(){
log.info("static str={}",str);
} String testSt(int n){
String res = "";
while (n > 0) {
res = res + startDate.toString() + "|" + n + "——";
n--;
}
return res;
} @Test
public void testU(){
TestStatic.test();
int n = 10;
testSt(n);
log.info("test {}:{}",n,testSt(n));
}
}

静态方法

  • 静态方法中没有this;
  • 静态方法中不能访问非静态成员方法和非静态成员变量,反之可以;

静态变量/常量

  • static成员变量的初始化顺序按照定义的顺序进行初始化;

静态代码块

  • static块可以置于类中的任何地方;
  • 一个类中可以有多个块;按顺序执行;
  • 只会在类加载的时候执行一次;
class Person{
private Date birthDate; public Person(Date birthDate) {
this.birthDate = birthDate;
} boolean isBornBoomer() {
Date startDate = Date.valueOf("1946");
Date endDate = Date.valueOf("1964");
return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
}
}

isBornBoomer是用来这个人是否是1946-1964年出生的,而每次isBornBoomer被调用的时候,都会生成startDate和birthDate两个对象,造成了空间浪费,如果改成这样效率会更好:

class Person{
private Date birthDate;
private static Date startDate,endDate;
static{
startDate = Date.valueOf("1946");
endDate = Date.valueOf("1964");
} public Person(Date birthDate) {
this.birthDate = birthDate;
} boolean isBornBoomer() {
return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
}
}

注意在代码块外进行声明,在代码块中执行初始化等操作;

题目考察

这段代码输出什么

public class Test {
Person person = new Person("Test");
static{
System.out.println("test static");
} public Test() {
System.out.println("test constructor");
} public static void main(String[] args) {
new MyClass();
}
} class Person{
static{
System.out.println("person static");
}
public Person(String str) {
System.out.println("person "+str);
}
} class MyClass extends Test {
Person person = new Person("MyClass");
static{
System.out.println("myclass static");
} public MyClass() {
System.out.println("myclass constructor");
}
}

我们还是来想一下这段代码的具体执行过程。首先加载Test类,因此会执行Test类中的static块。接着执行new MyClass(),而MyClass类还没有被加载,因此需要加载MyClass类。在加载MyClass类的时候,发现MyClass类继承自Test类,但是由于Test类已经被加载了,所以只需要加载MyClass类,那么就会执行MyClass类的中的static块。在加载完之后,就通过构造器来生成对象。而在生成对象的时候,必须先初始化父类的成员变量,因此会执行Test中的Person person = new Person(),而Person类还没有被加载过,因此会先加载Person类并执行Person类中的static块,接着执行父类的构造器,完成了父类的初始化,然后就来初始化自身了,因此会接着执行MyClass中的Person person = new Person(),最后执行MyClass的构造器。

test static
myclass static
person static
person Test
test constructor
person MyClass
myclass constructor

参考文章

最新文章

  1. CSS滚动条
  2. map的使用
  3. rmi远程调用
  4. SharpGL学习笔记(十九) 摄像机漫游
  5. Apache 日志分析(二)
  6. windows最基本命令行
  7. UVa 1395 (最小生成树) Slim Span
  8. shell排序算法
  9. PSAM 卡的应用操作方法
  10. Aprori算法[关联规则算法]
  11. Android开发之SoundPool使用具体解释
  12. SICP 1.20经验
  13. sjms-2 创建型模式
  14. c/c++ allocator 使用
  15. 配置SQLServer,允许远程连接
  16. &lt;转载&gt;ford-fulkerson算法
  17. Altmetric
  18. .NetCore源码阅读笔记系列之Security (三) Authentication &amp; AddOpenIdConnect
  19. 查询选修了全部课程的学生姓名_如何解?-MS-SQLServer/应用实例
  20. 使用curator框架简单操作zookeeper 学习笔记

热门文章

  1. 一个电商项目的Web服务化改造4:方案和架构,通用接口的定义和实现
  2. hdu_1861_游船出租_201402282130
  3. Clojure:通过ZeroMQ推送消息
  4. C++成员函数实现在类定义中与在类定义外的区别(Windows下直接使用g++)
  5. 【cocos2d-x 3.7 飞机大战】 决战南海I (十) 游戏主场景
  6. requireJS使用shim注入非标准模块详解
  7. Yum重装走过的坑
  8. 初入股市之 Hello Stock
  9. jsp页面中使用javascript获取后台放在request或session中的值
  10. vim中凝视多行python代码