关于Java中的static关键字
Java中的 static 关键字,确实是一个关键的字(key word),今天就来总结一下它的用法,说说为什么关键。
Java中的 static 关键字主要是用来做内存管理的。理解了这句话才能够比较深入地理解static。
static 可以修饰:
- 变量(所谓 class variable)
 - 方法(所谓 class method)
 - 代码块(所谓 block)
 - 内部类(所谓 nested class)
 
凡是被 static 修饰的这四种元素,都属于class的元素,即类的,而不是类的实例的。
1) 静态变量
在声明变量的时候加上 static ,该变量即是静态变量。
- 什么时候该用 static 来修饰变量呢?该变量被该类的所有实例所共享。
 - 静态变量在类被加载的时候初始化,且仅分配一次内存。
 
这样做的好处就是内存利用率高,看下下面两个demo:
// Understanding problem without static variable
class Student{
int stuNo;
String name;
String college="ITS";
}
假设这个"niubility my brother" 的学校有500000000个学生,那么当每一个学生被创建的时候,都会初始化学号、姓名、学校,每个学生都有自己的学号和姓名,这样做没问题;但是每个学生的college字段都相同,如果每次都声明一遍的话,是比较耗内存的。这里的college变量其实是被该类的所有实例所共享的,因此可以将它声明为 static 的。
//Program of static variable
class Student8{
int rollno;
String name;
static String college ="ITS"; Student8(int r,String n){
rollno = r;
name = n;
}
void display (){System.out.println(rollno+" "+name+" "+college);} public static void main(String args[]){
Student8 s1 = new Student8(111,"Karan");
Student8 s2 = new Student8(222,"Aryan"); s1.display();
s2.display();
}
}
Output:111 Karan ITS
222 Aryan ITS
看下实际内存分配情况:

静态变量分配在了方法区,堆中该类的所有实例共享方法区中的college。
再看一下下面这个栗子:Counter 类中声明了一个count变量,在构造函数中对其进行++操作,因为实例变量在对象被创建的时候分配内存,所有每一个对象都有一份自己的count副本,每个对象对各自count的++操作不会反应到其他对象上。
 class Counter{
 int count=0;//will get memory when instance is created  
 Counter(){
 count++;
 System.out.println(count);
 }  
 public static void main(String args[]){  
 Counter c1=new Counter();
 Counter c2=new Counter();
 Counter c3=new Counter();  
  }
 }  
Output:1
1
1
因为静态变量仅仅在类加载的时候分配一次内存,所以如果将count修饰为static,那么该类的所有对象将会共享该变量,每一个对象对count的操作都会反应到其他对象上。
 class Counter2{
 static int count=0;//will get memory only once and retain its value  
 Counter2(){
 count++;
 System.out.println(count);
 }  
 public static void main(String args[]){  
 Counter2 c1=new Counter2();
 Counter2 c2=new Counter2();
 Counter2 c3=new Counter2();  
  }
 }
Output:1
2
3
2)静态方法
在声明方法的时候加上 static 关键字,即静态方法:
- 静态方法属于类而不是对象。
 - 静态方法可以直接通过类名调用,而不需要创建类的对象。
 - 静态方法可以修改静态变量,而非静态方法不可以。
 
一个静态方法的栗子:
//Program of changing the common property of all objects(static field).
class Student9{
int rollno;
String name;
static String college = "ITS"; static void change(){
college = "BBDIT";
} Student9(int r, String n){
rollno = r;
name = n;
} void display (){System.out.println(rollno+" "+name+" "+college);} public static void main(String args[]){
Student9.change(); Student9 s1 = new Student9 (111,"Karan");
Student9 s2 = new Student9 (222,"Aryan");
Student9 s3 = new Student9 (333,"Sonoo"); s1.display();
s2.display();
s3.display();
}
}
Output:111 Karan BBDIT
222 Aryan BBDIT
333 Sonoo BBDIT
静态方法的第二颗栗子:
//Program to get cube of a given number by static method
class Calculate{
static int cube(int x){
return x*x*x;
} public static void main(String args[]){
int result=Calculate.cube(5);
System.out.println(result);
}
}
静态方法的两个注意点:
- 静态方法不能操作非静态变量,也不能调用非静态方法。(这个可以这样理解:静态方法属于类,直接通过类名就可以调用,而此时可能没有任何实例,更谈不上操作实例变量和调用实例方法了。)
 - 静态方法中不能使用 this 和 super 关键字。(道理同上)
 
 class A{
  int a=40;//non static  
  public static void main(String args[]){
   System.out.println(a);
  }
 }   
Output:Compile Time Error
Q)为什么Java的main方法是static的?
Ans)为了使得在调用main方法之前不需要创建任何实例对象。
3)静态代码块
为什么要有这个东西?干嘛用呢?
- 用来初始化静态变量。
 - 在类加载时,在执行main方法之前执行相关操作。
 
栗子:
 class A2{
   static{System.out.println("static block is invoked");}
   public static void main(String args[]){
    System.out.println("Hello main");
   }
 }  
Output:static block is invoked
Hello main
Q)没有main方法的程序可以执行吗?
Ans)可以,在JDK1.7之前执行如下代码是可以的:
 class A3{
   static{
   System.out.println("static block is invoked");
   System.exit(0);
   }
 }  
Output:static block is invoked (if not JDK7)
但是在JDK1.7会报如下错误:
Output:Error: Main method not found in class A3, please define the main method as:
public static void main(String[] args)
4)静态内部类
被static修饰的类,并且处于某个类的内部。
- 它可以访问外部类的静态成员,包括private成员。
 - 它不能访问外部类的非静态成员。(原因前面说过)
 
那么为什么要有静态内部类呢?看下面的栗子:
 class TestOuter1{
   static int data=30;
   static class Inner{
    void msg(){System.out.println("data is "+data);}
   }
   public static void main(String args[]){
   TestOuter1.Inner obj=new TestOuter1.Inner();
   obj.msg();
   }
 }  
Output:data is 30
main方法中创建了一个静态内部类的实例,并且调用了其msg() 方法。但是这里并没有创建外部类的实例,因为这里的Inner类是static的,并且可以访问外围类的static成员。如果把Inner之前的static去掉,那么这里要这样写:
TestStaticInnerClass.Inner obj=new TestStaticInnerClass().new Inner();
需要先创建外一个部类实例,然后才能创建内部类实例。静态内部类不仅高效利用内存,而且使得代码简洁。下面是static 内部类编译后的样子:
// Internal class generated by the compiler
import java.io.PrintStream;
static class TestOuter1$Inner
{
TestOuter1$Inner(){}
void msg(){
System.out.println((new StringBuilder()).append("data is ")
.append(TestOuter1.data).toString());
}
}
上例中,如果msg() 方法也是静态的,那么内部类的实例也不需要创建了:
 class TestOuter2{
   static int data=30;
   static class Inner{
    static void msg(){System.out.println("data is "+data);}
   }
   public static void main(String args[]){
   TestOuter2.Inner.msg();//no need to create the instance of static nested class
   }
 }  
Output:data is 30
以上是关于Java 中 static 关键字的理解,参考了:http://www.javatpoint.com/
关于Java中的static关键字的更多相关文章
- (转)Java中的static关键字解析
		
转载: http://www.cnblogs.com/dolphin0520/p/3799052.html 一.static关键字的用途 在<Java编程思想>P86页有这样一段话: &q ...
 - Java中的static关键字解析
		
Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...
 - (转)Java中的static关键字解析
		
转自http://www.cnblogs.com/dolphin0520/p/3799052.html 一.static关键字的用途 在<Java编程思想>P86页有这样一段话: “sta ...
 - Java中的static关键字解析 转载
		
原文链接:http://www.cnblogs.com/dolphin0520/p/3799052.html Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到 ...
 - Java中的static关键字解析(转自海子)__为什么main方法必须是static的,因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。
		
Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...
 - Java中的static关键字
		
写在前面: 在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在Java中static表示“全局”或“静态”的意思,用来修饰成员变量和成员方法,当然也可以修饰 ...
 - java中的static关键字详解
		
static对于我们这些初学者在编写代码和阅读代码是一个难以理解的关键字,也是大量公司面试题最喜欢考的之一.下面我就来就先讲述一下static关键字的用法和我们初学者容易误解的地方. static关键 ...
 - 【Java学习笔记之十五】Java中的static关键字解析
		
Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...
 - 再议Java中的static关键字
		
再议Java中的static关键字 java中的static关键字在很久之前的一篇博文中已经讲到过了,感兴趣的朋友可以参考:<Java中的static关键字解析>. 今天我们再来谈一谈st ...
 
随机推荐
- Python3.5+selenium操作Chrome浏览器
			
1.安装selenium 命令提示符下输入: pip install selenium 2.下载chromedriver 点击下载 3.将解压后的chromedriver.exe放到chrome浏览器 ...
 - pythonchallenge 解谜 Level 1
			
得到第一关地址后可以进行第一关的解析了. 看起来好神秘的样子.但是也就是把字母 k 变成 m , o 变成 q ,e 变成 g.将字母对应的ASCII的值+2就行了. #-*- coding:utf- ...
 - Struts2登录小例子
			
前面实现了一个数据显示的例子,下面我来实现以下使用Struts2登录 首先是配置不用过多解释 注意名字要和类名保持一致 因为实现的是action这个方法所以需要用action.log来跳转到类里面 解 ...
 - ReactJS入门(三)—— 顶层API
			
本文基本跟着官方文档把API都走一遍,但会有实例来解释应该怎么用,木有比我更详细的API文档咯. React.createClass 参数:CONFIG(object) 创建一个ReactClass( ...
 - 老司机学Xamarin系列总目录
			
Xamarin开发环境及开发框架初探 Xamarin Forms开发框架二探 (Prism vs MvvmCross) Xamarin Forms开发框架之MvvmCross插件精选 Xamarin开 ...
 - Worktile协同特色之二:任务看板管理
			
什么是看板 看板是一种使用可视化管理的方式,跟踪任务在整个价值流中流经的不同阶段,通常我们会用带贴纸的白板,或是电子卡片墙.具备如下几个特征:1. 流程可视化 把工作拆分成小块,一张卡片写一件任务,再 ...
 - 操作数据库mysql
			
显示表结构 desc 表 显示数据库信息 show create database 数据库名 show create table 表名
 - Android开发学习之路-让注解帮你简化代码,彻底抛弃findViewById
			
本文主要是记录注解的使用的学习笔记,如有错误请提出. 在通常的情况下,我们在Activity中有一个View,我们要获得这个View的实例是要通过findViewById这个方法,然后这个方法返回的是 ...
 - 王宝强新片P2P风波持续发酵,互金真的前途未卜?
			
王宝强离婚风波还未完全结束,一波未平一波又起,新片又引来话题爆点,其自导自演的电影<大闹天竺>陷P2P平台集资的新闻占据各大媒体头条. 该P2P平台为湖北武汉一家P2P互联网金融理财平台& ...
 - Android笔记——permission权限大全
			
访问登记属性 android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权限 获取错略位置 android.permiss ...