转载自大佬: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. Python:numpy中shape和reshape的用法

    >>> w=np.zeros((5,6))>>> warray([[ 0.,  0.,  0.,  0.,  0.,  0.],       [ 0.,  0.,  ...

  2. 深入理解 web 协议(一)- http 包体传输

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/WlT8070LlrnSODFRDwZsUQ作者:吴越 开坑这个系列的原因,主要是在大前端学习的 ...

  3. angular之跨域

    一.什么是跨域? 跨域是指一个域下的文档或者脚本去请求另一个域下的资源.(广义) 广义的跨域: 1.资源跳转:链接跳转.重定向.表单提交. 2.资源嵌入:<link>.<script ...

  4. opencv::源码编译

    环境:win10.vs2017.cmake .java.python3.7默认安装. opencv源码:opencv-.zip opencv拓展库源码:opencv_contrib-.zip (注意: ...

  5. 安装Go语言及搭建Go语言开发环境

    一步一步,从零搭建Go语言开发环境. 安装Go语言及搭建Go语言开发环境 下载 下载地址 Go官网下载地址:https://golang.org/dl/ Go官方镜像站(推荐):https://gol ...

  6. pycharm中如何为项目设置默认执行器?

    一般来说,在python中如果定义了test开头的函数,pycharm会使用默认的执行器.如下方法可以修改默认执行器: file->Setting:打开setting设置页面

  7. webpack 4.x 初级学习记录

    首先声明下,本人不擅长文字表达,文采不行,所以文章中文字较少,请看代码,初级学习,不足之处请多多指教 GitHub链接 看云kancloud [TOC] webpack 4.x 安装 首先需要在全局中 ...

  8. 用Python编写简单的发红包程序和计算器原理

    用Python编写简单的发红包程序: 第一种解法:数轴方法解决 import random def red_packet(money,num): money = money * 100 #将钱数转换成 ...

  9. 面向对象的7个设计原则->开车理解->贴近生活

    设计模式在我们的开发中是不可或缺的一部分,很多人会说,我没用那些设计模式啊,我也开发的挺好的,其实不然,我们在开发中都用到了这些设计模式,只不过我们并没有在意这些,今天我就用开车的方法来解释一下我们的 ...

  10. 谷歌黑客语法(google hacking)让你的搜索更精准有效

    Google Hacking的含义原指利用Google Google搜索引擎搜索信息来进行入侵的技术和行为: 现指利用各种搜索引擎搜索信息来进行入侵的技术和行为,但我们也可以利用这个在互联网上更加便捷 ...