static 修饰符能够与变量、方法一起使用,表示是“静态”的。

静态变量和静态方法能够通过类名来访问,不需要创建一个类的对象来访问该类的静态成员,所以static修饰的成员又称作类变量和类方法。静态变量与实例变量不同,实例变量总是通过对象来访问,因为它们的值在对象和对象之间有所不同。

请看下面的例子:

 public class Demo {
static int i = 10;
int j;
Demo() {
this.j = 20;
}
public static void main(String[] args) {
System.out.println("类变量 i=" + Demo.i);
Demo obj = new Demo();
System.out.println("实例变量 j=" + obj.j);
}
}

运行结果:

类变量 i=10
实例变量 j=20

static 的内存分配

静态变量属于类,不属于任何独立的对象,所以无需创建类的实例就可以访问静态变量。之所以会产生这样的结果,是因为编译器只为整个类创建了一个静态变量的副本,也就是只分配一个内存空间,虽然有多个实例,但这些实例共享该内存。实例变量则不同,每创建一个对象,都会分配一次内存空间,不同变量的内存相互独立,互不影响,改变 a 对象的实例变量不会影响 b 对象。

请看下面的代码:

 public class Demo {
static int i;
int j;
public static void main(String[] args) {
Demo obj1 = new Demo();
obj1.i = 10;
obj1.j = 20; Demo obj2 = new Demo(); System.out.println("obj1.i=" + obj1.i + ", obj1.j=" + obj1.j);
System.out.println("obj2.i=" + obj2.i + ", obj2.j=" + obj2.j);
}
}

运行结果:

obj1.i=10, obj1.j=20
obj2.i=10, obj2.j=0

注意:静态变量虽然也可以通过对象来访问,但是不被提倡,编译器也会产生警告。

上面的代码中,i 是静态变量,通过 obj1 改变 i 的值,会影响到 obj2;j 是实例变量,通过 obj1 改变 j 的值,不会影响到 obj2。这是因为 obj1.i 和 obj2.i 指向同一个内存空间,而 obj1.j 和 obj2.j 指向不同的内存空间,请看下图:


图1  静态变量内存分配

注意:static 的变量是在类装载的时候就会被初始化。也就是说,只要类被装载,不管你是否使用了这个static 变量,它都会被初始化。

小结:类变量(class variables)用关键字 static 修饰,在类加载的时候,分配类变量的内存,以后再生成类的实例对象时,将共享这块内存(类变量),任何一个对象对类变量的修改,都会影响其它对象。外部有两种访问方式:通过对象来访问或通过类名来访问。

静态方法

静态方法是一种不能向对象实施操作的方法。例如,Math 类的 pow() 方法就是一个静态方法,语法为 Math.pow(x, a),用来计算 x 的 a 次幂,在使用时无需创建任何 Math 对象。

因为静态方法不能操作对象,所以不能在静态方法中访问实例变量,只能访问自身类的静态变量。

以下情形可以使用静态方法:

  • 一个方法不需要访问对象状态,其所需参数都是通过显式参数提供(例如 Math.pow())。
  • 一个方法只需要访问类的静态变量。

读者肯定注意到,main() 也是一个静态方法,不对任何对象进行操作。实际上,在程序启动时还没有任何对象,main() 方法是程序的入口,将被执行并创建程序所需的对象。

关于静态变量和静态方法的总结:

  • 一个类的静态方法只能访问静态变量;
  • 一个类的静态方法不能够直接调用非静态方法;
  • 如访问控制权限允许,静态变量和静态方法也可以通过对象来访问,但是不被推荐;
  • 静态方法中不存在当前对象,因而不能使用 this,当然也不能使用 super;
  • 静态方法不能被非静态方法覆盖;
  • 构造方法不允许声明为 static 的;
  • 局部变量不能使用static修饰。

静态方法举例:

 public class Demo {
static int sum(int x, int y){
return x + y;
}
public static void main(String[] args) {
int sum = Demo.sum(10, 10);
System.out.println("10+10=" + sum);
}
}

运行结果:

10+10=20

static 方法不需它所属的类的任何实例就会被调用,因此没有 this 值,不能访问实例变量,否则会引起编译错误。

注意:实例变量只能通过对象来访问,不能通过类访问。

静态初始器(静态块)

块是由大括号包围的一段代码。静态初始器(Static Initializer)是一个存在于类中、方法外面的静态块。静态初始器仅仅在类装载的时候(第一次使用类的时候)执行一次,往往用来初始化静态变量。

示例代码:

 public class Demo {
public static int i;
static{
i = 10;
System.out.println("Now in static block.");
}
public void test() {
System.out.println("test method: i=" + i);
}
public static void main(String[] args) {
System.out.println("Demo.i=" + Demo.i);
new Demo().test();
}
}

运行结果是:

Now in static block.
Demo.i=10
test method: i=10

静态导入

静态导入是 Java 5 的新增特性,用来导入类的静态变量和静态方法。

一般我们导入类都这样写:

 import packageName.className; // 导入某个特定的类

 import packageName.*; // 导入包中的所有类

而静态导入可以这样写:

 import static packageName.className.methonName; // 导入某个特定的静态方法

 import static packageName.className.*; // 导入类中的所有静态成员

导入后,可以在当前类中直接用方法名调用静态方法,不必再用 className.methodName 来访问。

对于使用频繁的静态变量和静态方法,可以将其静态导入。静态导入的好处是可以简化一些操作,例如输出语句 System.out.println(); 中的 out 就是 System 类的静态变量,可以通过 import static java.lang.System.*; 将其导入,下次直接调用 out.println() 就可以了。

请看下面的代码:

 import static java.lang.System.*;
import static java.lang.Math.random;
public class Demo {
public static void main(String[] args) {
out.println("产生的一个随机数:" + random());
}
}

运行结果:

产生的一个随机数:0.05800891549018705

Java知多少(31)static关键字以及Java静态变量和静态方法的更多相关文章

  1. Java:final、static关键字 详解+两者结合使用

    一  final关键字 1) 关于final的重要知识点 final关键字可以用于成员变量.本地变量.方法以及类. final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误. ...

  2. “全栈2019”Java第四十一章:static关键字

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  3. Java中final和static关键字总结

    1.final: final关键字可用于类.方法.变量前. final修饰的类不可被继承,例如java.lang.Math就是一个 final类,不可被继承. final修饰变量,在显示初始化后不可改 ...

  4. 《Java基础知识》Java static关键字以及Java静态变量和静态方法

    static 修饰符能够与变量.方法一起使用,表示是“静态”的. 静态变量和静态方法能够通过类名来访问,不需要创建一个类的对象来访问该类的静态成员,所以static修饰的成员又称作类变量和类方法.静态 ...

  5. Java继承和多态-Static关键字

    1. 什么是Static 关键字? Static 能够与变量,方法和类一起使用,称为静态变量,静态方法.如果在一个类中使用static修饰变量或者方法的话,它们可以直接通过类访问,不需要创建一个类的对 ...

  6. java===java基础学习(13)---this,static(静态变量和静态方法)的使用

    package dog; public class PersonAndDog { public static void main(String[] args) { Dogs da_huang = ne ...

  7. JAVA的静态变量、静态方法、静态类

    静态变量和静态方法都属于静态对象,它与非静态对象的差别需要做个说明. (1)Java静态对象和非静态对象有什么区别? 比对如下: 静态对象                                ...

  8. 转载:JAVA的静态变量、静态方法、静态类

    静态变量和静态方法都属于静态对象,它与非静态对象的差别需要做个说明. (1)Java静态对象和非静态对象有什么区别? 比对如下: 静态对象                                ...

  9. Java:【面向对象:类的定义,静态变量,成员变量,构造函数,封装与私有,this】

    本文内容: 什么是面对对象 类的定义与对象实例化 成员变量 成员变量的有效范围 成员变量的赋值 静态变量.方法与实例变量.方法 构造函数 封装与私有 this关键字 注:函数和方法是一样东西.[由于我 ...

随机推荐

  1. ruby那些事儿

    为了学习sass,客串一下ruby,这是一个破案的过程,探索的过程. Ruby是日本人发明的一种类似于Python和Perl的服务器端脚本语言,它完全面向对象,适合于快速开发,一般开发效率是java的 ...

  2. 排序遇到问题 JDK7的Comparison method violates its general contract

    图解JDK7的Comparison method violates its general contract异常 楼主分析的很详细,能力有限,我看得迷迷糊糊的,不过大致知道这个错误的起因了.学习了,谢 ...

  3. IT 产品 需求 痛点

    英文应该有个 汉语发音 标注 这样的平台软件.罗马音.

  4. ModelForm的使用

    from django.forms import Form,ModelForm,fields,widgets as wd class QueModelForm(ModelForm): class Me ...

  5. ftp命令详解补充

     下面我来详细地介绍一个登陆FTP的命令和步骤吧: FTP命令是Internet用户使用最频繁的命令之一,不论是在DOS还是UNIX操作系统下使用FTP,都会遇到大量的FTP内部命令.熟悉并灵活应用F ...

  6. Windows远程桌面,连接被拒绝,因为没有授权此用户帐户进行远程登录。

    Windows 服务器远程连接的时候,出现错误:“连接被拒绝,因为没有授权此用户帐户进行远程登录.”,导致无法远程登录服务器,如下图所示: 问题分析 该错误一般是由于 Windows 远程桌面相关权限 ...

  7. Shell Step by Step (4) —— Cron & Echo

    6.脚本定时任务 # Example of job definition: # .------------------------- minute (0 - 59) # | .------------ ...

  8. EasyUI学习总结(二)——easyloader分析与使用(转载)

    本文转载自:http://www.cnblogs.com/haogj/archive/2013/04/22/3036685.html 使用脚本库总要加载一大堆的样式表和脚本文件,在easyui 中,除 ...

  9. Opencv中Mat矩阵相乘——点乘、dot、mul运算详解

    Opencv中Mat矩阵相乘——点乘.dot.mul运算详解 2016年09月02日 00:00:36 -牧野- 阅读数:59593 标签: Opencv矩阵相乘点乘dotmul 更多 个人分类: O ...

  10. Go语言之高级篇beego框架之config、httplib、context

    一.httplib 1.配置文件解析 这是一个用来解析文件的库,它的设计思路来自于 database/sql,目前支持解析的文件格式有 ini.json.xml.yaml,可以通过如下方式进行安装: ...