static 关键字的主要功能
1. 修饰变量
2.修饰方法
3. 静态代码块
4.(还可以修饰内部类)
一 修饰变量
1.静态变量 只能修饰成员变量,在内存里只有一份,类的所有实例共享这一份静态变量,非静态变量属于对象 每创建一个对象,都有一份与之对应。
2 .两者在内存中的位置不一样,静态变量在方法区中,非静态变量在堆中。
3.调用方式一样:静态变量的调用可以通过new一个对象调用(但不推荐,,java会给出警告),不同类中:一般使用类名.变量名调用变量;非静态变量只能通过new一个对象进行调用。对于同一类中:由static修饰的变量,可以直接使用它,至于用static修饰的方法,在该类中可以直接调用方法名调用该方法,非静态变量和非静态方法还是需要通过创建对象来调用。
4.加载时间不一样:静态变量与类一起加载,非静态变量与对象一起加载。
例子:
public class User {
private static int userNumber = 0 ;
public User(){
userNumber ++;
}
public static void main(String[] args) {
User user1 = new User();
User user2 = new User();
System.out.println("user1 userNumber:" + User.userNumber);
System.out.println("user2 userNumber:" + User.userNumber);
}
}
------------
Output:
user1 userNumber:2
user2 userNumber:2
例二:
public class User {
private int userNumber = 0 ;
public User(){
userNumber ++;
}
public static void main(String[] args) {
User user1 = new User();
User user2 = new User();
System.out.println("user1 userNumber:" + user1.userNumber);
System.out.println("user2 userNumber:" + user2.userNumber);
}
}
output:
user1 userNumber:1
user1 userNumber:1
二 修饰方法
当一个方法是用静态关键字声明,它被称为静态方法。最常见的例子,一个静态方法是main()方法。正如上面所讨论的,任何静态成员可以访问它的类的任何对象创建之前,并没有引用任何对象。方法声明为静态有几个限制:
2.静态方法只能继承,不能重写(Override)。
4 .静态方法不能出现出现this和super关键字。 解释一下:由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。
例子:
class
Student
{
String name;
int
rollNo;
// static variable
static
String cllgName;
// static counter to set unique roll no
static
int
counter =
0
;
public
Student(String name)
{
this
.name = name;
this
.rollNo = setRollNo();
}
// getting unique rollNo
// through static variable(counter)
static
int
setRollNo()
{
counter++;
return
counter;
}
// static method
static
void
setCllg(String name){
cllgName = name ;
}
// instance method
void
getStudentInfo(){
System.out.println(
"name : "
+
this
.name);
System.out.println(
"rollNo : "
+
this
.rollNo);
// accessing static variable
System.out.println(
"cllgName : "
+ cllgName);
}
}
//Driver class
public
class
StaticDemo
{
public
static
void
main(String[] args)
{
// calling static method
// without instantiating Student class
Student.setCllg(
"XYZ"
);
Student s1 =
new
Student(
"Alice"
);
Student s2 =
new
Student(
"Bob"
);
s1.getStudentInfo();
s2.getStudentInfo();
}
}
Output:
name : Alice
rollNo : 1
cllgName : XYZ
name : Bob
rollNo : 2
cllgName : XYZ
三 静态代码块
静态代码块在类被加载的时候执行,而构造方法是在生成对象的时候执行;要想调用某个类来生成对象,首先需要将类加载到Java虚拟机上(JVM),然后由JVM加载这个类来
生成对象。
如果你需要做计算为了初始化静态变量,您可以声明一个静态块被完全执行一次,第一次加载类时。static关键字还有一个比较关键的作
用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,
会按照static块的顺序来执行每个static块,并且只会执行一次。
为什么说static块可以用来优化程序性能,是因为它的特性:只会在类
加载的时候执行一次。
例子:
class
Test
{
public Test(){
System.out.println("我是构造方法");
}
static
{
System.out.println(
"我是静态代码块"
);
}
public
static
void
main(String[] args)
{
Test t1=new Test();
Test t2 =new Test();
Test t3=new Test();
}
}
outout:
我是静态代码块
我是构造方法
我是非静态代码块
我是构造方法
我是非静态代码块
我是构造方法
我是非静态代码块
如果体系中既有构造方法,又有静态代码块,那么首先执行最顶层的类的静态代码块,一直执行到最底层类的静态代码块,然后再去执行最顶层类的构造方法,一直执行到最底层类的构造方法。