转载自大佬:https://www.cnblogs.com/xrq730/p/4820992.html

静态资源和静态方法

首先,静态的资源和方法等会随着类的加载而进入内存被初始化,而非静态的资源和方法会随着new的动作被初始化。即,静态先,非静态后。

由于这种特性,我们可以理解static的基本用法:

1、被static修饰的变量属于类变量,可以通过类名.变量名直接引用,而不需要new出一个类来

2、被static修饰的方法属于类方法,可以通过类名.方法名直接引用,而不需要new出一个类来

被static所修饰的变量是唯一的静态资源,是各个对象实例化后所共享的资源,则静态资源被改变后,所有实例中的该资源都会改变。

下面来理解一个问题:静态方法能不能调用非静态资源?以下面代码为例

public class A
{
private int i = 1; public static void main(String[] args)
{
i = 1;
}
}

main方法是静态方法,i是非静态资源。在类加载进入内存时,main方法初始化,方法中的所有资源都要被加载进内存。而由于i是非静态资源,要通过new来初始化,所以i并不能进入内存。

所以我们可以得到以下结论:

  1,静态方法不能调用非静态资源

  2,静态方法可以调用静态资源

  3,非静态方法可以调用静态资源

静态代码块

  静态块的语法如下

static{
statments;
........
}

静态块是用于初始化一个类的时候同时进行一些操作的。静态块中的代码只在初始化类的时候执行一次。

public class A
{
private static int a = B(); static
{
System.out.println("Enter A.static block");
} public static void main(String[] args)
{
new A();
} public static int B()
{
System.out.println("Enter A.B()");
return 1;
}
}

打印结果:

Enter A.B()
Enter A.static block

我们看到,在main方法中,首先new了对象A,按顺序加载a=B(),调用方法B,打印Enter A.B(); 然后打印静态块中的内容。

可以得到结论:静态资源的加载顺序是严格按照静态资源的定义顺序来加载的

再看一个例子:

 1 public class A
2 {
3 static
4 {
5 c = 3;
6 System.out.println(c);
7 }
8
9 private static int c;
10 }

这段代码的第6行是有错误的“Cannot reference a field before it is defined”。从这个例子得出第二个结论:静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问

最后一个小例子:

 1 public class A
2 {
3 static
4 {
5 System.out.println("A.static block");
6 }
7
8 public A()
9 {
10 System.out.println("A.constructor()");
11 }
12 }
 1 public class B extends A
2 {
3 static
4 {
5 System.out.println("B.static block");
6 }
7
8 public B()
9 {
10 System.out.println("B.constructor()");
11 }
12
13 public static void main(String[] args)
14 {
15 new B();
16 new B();
17 }
18 }

结果是

A.static block
B.static block
A.constructor()
B.constructor()
A.constructor()
B.constructor()

这个例子得出第三个结论:静态代码块是严格按照父类静态代码块->子类静态代码块的顺序加载的,且只加载一次

static修饰类

这个用得相对比前面的用法少多了,static一般情况下来说是不可以修饰类的,如果static要修饰一个类,说明这个类是一个静态内部类(注意static只能修饰一个内部类),也就是匿名内部类。像线程池ThreadPoolExecutor中的四种拒绝机制CallerRunsPolicy、AbortPolicy、DiscardPolicy、DiscardOldestPolicy就是静态内部类。静态内部类相关内容会在写内部类的时候专门讲到。    待补充

import static

这个比较冷门,基本很少看见有地方用,使用JUnit可能会用到,写assert的时候会方便些。import static是JDK1.5之后的新特性,这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名.资源名,可以直接使用资源名。注意一下,import static必须这么写,而不能写成static import。举个例子来看一下:

package chapter3Demos;

import static java.lang.System.out;

import static java.lang.Math.*;

public class Demo3_3_2 {

    public static void main(String[] args)  {
out.println(sin(2.2));
}
}

第一个import static表示直接指定导入out这个静态资源,可以省略写System,但是不能使用其他System类中的静态方法。

第二个import static表示导入了Math类中所有的静态方法,不仅sin可以不写Math,其他数学函数也可以省略不写

这种写法减少了代码量,简化了一些操作,但是降低了代码的可读性。

除了在一些特定场合用到之外,建议不要使用。

static静态关键字的更多相关文章

  1. Java中static静态关键字的使用

    我们可以基于一个类创建多个对象,每个对象都拥有自己的成员,所有成员变量的值是根据对象而存在的,有些时候我们希望一个类的所有对象共享一个成员,这就用到了static静态关键字 被静态关键字修饰的成员属于 ...

  2. php笔记(二)PHP类和对象之Static静态关键字

      PHP类和对象之Static静态关键字 静态属性与方法可以在不实例化类的情况下调用,直接使用类名::方法名的方式进行调用.静态属性不允许对象使用->操作符调用. class Car { pr ...

  3. php中static静态关键字的使用

    php中除了常规类和方法的使用,访问控制之外,还有静态关键字static,静态变量可以是局部变量也可以是全局变量,当一个程序段执行完毕时,静态变量并没有消失,它依然存在于内存中,下次在定义时还是以前的 ...

  4. php中static静态关键字的使用方法和应用场景

    php中除了常规类和方法的使用,访问控制之外,还有静态关键字static,静态变量可以是局部变量也可以是全局变量,当一个程序段执行完毕时,静态变量并没有消失,它依然存在于内存中,下次在定义时还是以前的 ...

  5. Java之static静态关键字详解|final关键字详解

    前言 在Java语言中,static表示"静态"的意思,使用场景可以用来修饰成员变量和成员方法,当然也可以是静态代码块.static的主要作用在于创建独立于具体对象的域变量或者方法 ...

  6. php中static 静态关键字

    一直依赖对于php中static关键字比较模糊,只是在单例模式中用过几次.上网查了查,没有找到很全的介绍,自己总结一下. 根据使用位置分为两部分 1.函数体中的静态变量 2.类中的静态属性和方法 1 ...

  7. static(静态)关键字

    class Person{String name; //成员变量,实例变量(实例中的变量) //共享数据出现在对象之前static String country="cn"; //对 ...

  8. Java static静态关键字 有啥用

    #static有啥用 在Java语言中,static表示“静态”的意思,使用场景可以用来修饰成员变量和成员方法,当然也可以是静态代码块.static的主要作用在于创建独立于具体对象的域变量或者方法. ...

  9. php Static静态关键字

    静态属性与方法可以在不实例化类的情况下调用,直接使用类名::方法名的方式进行调用.静态属性不允许对象使用->操作符调用. class Car { private static $speed =  ...

随机推荐

  1. Web渗透之mssql2005 差异备份getshell

    这里记录下mssql2005差异备份拿shell的过程 http://192.168.5.21:81/index.asp?id=1;alter/**/database/**/[asp_test]/** ...

  2. 流包装器实现WebShell免杀

    说明: 本文首发自 https://www.secpulse.com/archives/73391.html ,转载请注明出处. 前言 本文是看PHP使用流包装器实现WebShell有感,权当做个笔记 ...

  3. JS中作用域和作用域链

    1.执行环境(execution context) 执行环境定义了变量和函数有权访问的其他数据,决定了他们各自的行为.每个执行环境都有与之对应的变量对象(variable object),保存着该环境 ...

  4. MariaDB数据库

      MySQL作者Michael Widenius自己创办了新公司Monty Program AB,在MySQL基础上新创了MariaDB开源数据库.MariaDB带来更好的数据库管理特性,更好的自由 ...

  5. 说说hashCode() 和 equals() 之间的关系?

    上一篇关于介绍Object类下的几种方法时面试题时,提到equals()和hashCode()方法可能引出关于“hashCode() 和 equals() 之间的关系?”的面试题,本篇来解析一下这道基 ...

  6. 4. SOFAJRaft源码分析— RheaKV初始化做了什么?

    前言 由于RheaKV要讲起来篇幅比较长,所以这里分成几个章节来讲,这一章讲一讲RheaKV初始化做了什么? 我们先来给个例子,我们从例子来讲: public static void main(fin ...

  7. mac本地安装单机hadoop--学习笔记

    Mac配置hadoop1.修改 /etc/hosts127.0.0.1 localhost2.下载hadoop2.9.0和jdk并安装配置相应环境 vim /etc/profile export HA ...

  8. JVM(8) 线程安全与锁优化

    面向过程编程:程序编写以算法为核心,程序员会把数据和过程分别作为独立的部分来考虑,数据代表问题空间的客体,程序代码则用于处理这些数据.这种思维方式直接站在计算机的角度去抽象问题和解决问题,称为面向过程 ...

  9. fenby C语言 P12

    条件语句的嵌套 注意格式对齐 #include <stdio.h> int main(){ int score=67; if(score<=100&&score> ...

  10. Shiro框架 - 【shiro基础知识】

     转载:https://segmentfault.com/a/1190000013875092#articleHeader27  读完需要 63 分钟   前言 本文主要讲解的知识点有以下: 权限管理 ...