Java中的static关键字
static的基本概念
在Java中static关键字是一个修饰词,可以修饰类中的数据成员,也可以修饰类中的成员函数,但是不能在主类的main方法中使用static修饰对象,在主类中main方法外使用static关键字修饰的子方法可以在main方法中直接调用。除此之外,Java中的static可以修饰代码块,这一点在C/C++中就没有。
static修饰类中的成员
static只能在自定义的类中修饰里面的成员,在主方法中使用static修饰对象会报错。
直接看代码:
class Man{
public String name;
public static int money;
public Man(String name,int money){
this.name=name;
this.money=money;
}
public void printInfo(){
System.out.println("姓名:"+this.name);
System.out.println("金钱:"+this.money);
}
}
public class Demo {
public static void main(String[] args) {
Man man=new Man("Jack",1001);
man.printInfo();
Man.money=99999;
man.printInfo();
}
}
输出结果:
姓名:Jack
金钱:1001
姓名:Jack
金钱:99999
上面的程序就是用static修饰Man类中的money属性,这个时候money是属于整个Man类的,而不是Man类的某个对象特有。当我们使用Man类名直接调用money属性的时候是可以的,并且修改里面的值之后,Man的对象man的money属性也随之改变。
这个很好理解,举一个简单的白话版的例子:
现在有一个班级class,这个是一个类,班级里有一个黑板,这个是类的属性,这个黑板是所有学生共有的,这个班级的学生就是这个班级的对象,那么这个黑板就是属于这整个班级的不是某个学生特有的。这个班级上的所有学生都可以使用这个黑板,当同学A在黑板上写了个字,在B同学眼睛里看到的黑板是被A同学写了个字的黑板,同样C同学的黑板也是这个已经写了字的黑板,现在B同学去把黑板上的字擦掉,那么在A同学和C同学的眼中看到的黑板就没有之前的字了。那这个黑板就是用static修饰的。而没有被static修饰的属性就是对象自己特有的,就像是A同学的名字是A,B同学的名字是B,如果A同学把名字改成了a那影响的也只是A同学而已,B同学的名字还是B。
然后再看一下代码:塑料英语,忍一下
class MyClass{
private String name;
private static String blackboard;
public MyClass(){}
public MyClass(String name,String blackboard){
this.name=name;
this.blackboard=blackboard;
}
public String getName(){
return this.name;
}
public String getBlackboard(){
return this.blackboard;
}
public void setName(String name){
this.name=name;
}
public void setBlackboard(String blackboard){
this.blackboard=blackboard;
}
}
public class Demo {
public static void main(String[] args) {
MyClass Jack=new MyClass("Jack","");
MyClass Alice=new MyClass("Alice","");
//Jack writes words on our blackboard. The word is I Love Java programs.
Jack.setBlackboard("I Love Java programs.");
//In Alice view, the word on blackboard is I Love Java programs
System.out.println("In Alice view : "+Alice.getBlackboard());
System.out.println("In Jack view : "+Jack.getBlackboard());
//Alice writes words on our blackboard. The word is I Love C Plus Plus programs.
//By this time, Jack's words had been cleared by Alice
Alice.setBlackboard("I Love C Plus Plus programs.");
//Then we print information of Jack and Alice.
System.out.println("Information of Alice : "+Alice.getName()+'\t'+Alice.getBlackboard());
System.out.println("Information of Jack : "+Jack.getName()+'\t'+Jack.getBlackboard());
//Change Jack's name to JayChou.
Jack.setName("JayChou");
//Then we print information of Jack and Alice.
System.out.println("Information of Alice : "+Alice.getName()+'\t'+Alice.getBlackboard());
System.out.println("Information of Jack : "+Jack.getName()+'\t'+Jack.getBlackboard());
}
}
输出结果:
In Alice view : I Love Java programs.
In Jack view : I Love Java programs.
Information of Alice : Alice I Love C Plus Plus programs.
Information of Jack : Jack I Love C Plus Plus programs.
Information of Alice : Alice I Love C Plus Plus programs.
Information of Jack : JayChou I Love C Plus Plus programs.
从代码中可以知道的是,static修饰的数据成员是属于整个类的,不是属于某个对象特有。在上面的代码中,Jack先在黑板上写了I Love Java programs.然后用Alice对象访问的这个静态数据成员的时候打印的是这句话,但一开始Alice并没有给blackboard成员写什么,初始化是一个空字符串,后来Alice写了I Love C Plus Plus programs.然后通过Jack对象访问blackboard成员的时候打印的I Love C Plus Plus programs.因为Java不能直接使用类名直接调用但是要知道的就是被static修饰的是属于整个类的,或者说是属于这个类所有对象的,不是某个对象特有。
static修饰主类中的方法
在主类中用static关键字修饰方法可以方便main方法直接调用这个方法,如果不用static修饰的话,main方法想调用也可以,不过要先创建一个无名的主类对象,然后才能调用。
直接看代码来理解:
public class Demo02 {
public static void main(String[] args) {
functionHaveStatic(); //直接调用是没有任何问题的
//functionHaveNotStatic(); 这样调用是会报错的
//无法从 static 上下文引用非 static 方法 'functionHaveNotStatic()'
new Demo02().functionHaveNotStatic(); //这样调用才没有问题
}
public static void functionHaveStatic(){
System.out.println("This function have static attribute.");
}
public void functionHaveNotStatic(){
System.out.println("This function have not static attribute.");
}
}
输出结果:
This function have static attribute.
This function have not static attribute.
static修饰类中的方法
在自己写的类中的方法也是可以用static修饰的,这些被static修饰的成员方法只能调用被static修饰的数据成员,因为被static的是属于整个类的,所有只能调用没有实例化对象的类的属性,那就只有静态数据成员有这个特点。
直接看代码吧:
package base07;
class Test{
public int testNum;
public static int testStaticNum;
public static void staticFunction(){
System.out.println("This function have static attribute.");
//System.out.println("testNum = "+this.testNum); 静态成员方法只能调用静态数据成员
System.out.println("testStaticNum = "+testStaticNum);
}
public void Function(){
System.out.println("This function have not static attribute.");
System.out.println("testNum = "+this.testNum);
System.out.println("testStaticNum = "+testStaticNum); //非静态函数可以调用静态数据成员
}
}
public class Demo03 {
public static void main(String[] args) {
Test test=new Test();
test.staticFunction();
test.Function();
}
}
输出结果:
This function have static attribute.
testStaticNum = 0
This function have not static attribute.
testNum = 0
testStaticNum = 0
static修饰代码块
代码块就是用{}单纯地括起来的块叫代码块
{
这个就是一个普通的代码块
}
代码块有优先执行的特性,使用static修饰的代码块执行的优先级更高
static{
这个是静态代码块
}
直接看代码:
public class Demo01{
public static void main(String[] args){
System.out.println("执行main方法中的代码");
}
static {
System.out.println("执行static修饰的代码块中的代码");
}
}
输出结果:
执行static修饰的代码块中的代码
执行main方法中的代码
在主方法中不能有static修饰的代码块:
public class Demo01{
public static void main(String[] args){
System.out.println("执行main方法中的代码");
//static {
// System.out.println("执行static修饰的代码块中的代码");
//}
//应为标识符或类型
}
}
在主方法中不仅不能有static修饰的代码块,static都不能在主方法中修饰对象,编译器会报错。
public class Demo01{
public static void main(String[] args){
System.out.println("执行main方法中的代码");
//static int i=0;
//此处不允许使用修饰符 'static'
}
}
在类中的静态代码块只在创建第一个类的对象执行一次,之后再创建对象就不再执行静态代码块的内容,在类中,静态代码块也是优先执行的。
直接看代码:
class Test {
static {
System.out.println("This Test class static code block");
}
public void fun(){
System.out.println("This fun");
}
}
public class Demo01{
public static void main(String[] args){
Test obj1=new Test();
obj1.fun();
Test obj2=new Test();
obj2.fun();
}
}
输出结果:
This Test class static code block
This fun
This fun
简单小结
- static是修饰词,可以修饰数据成员,可以修饰方法和成员方法,也可以修饰代码块
- 在类中被static修饰的数据成员和成员方法属于整个类,或者说属于类的所有对象,不是某个对象特有
- 在类中使用static修饰的成员方法只能调用被static修饰的数据成员或成员方法
- 在主类中使用static修饰的方法可以直接在main方法中调用
- 在主类中没有使用static修饰的方法必须创建主类对象后才能通过主类对象调用
- 使用static修饰的代码块在程序执行中优先执行,比普通的代码块优先级高
- 无论创建多少次类的对象,在类中的静态代码块只执行一次,而且最优先执行
关注我你会知道更多!!!
Cukor主页