java基础:static关键字,静态

static关键字的用法

static 可以用来修饰属性,方法,代码块

1、静态属性

定义

使用static关键字修饰的属性就是静态属性
如:

static int num;
1.1 用法

(1)可以直接使用类名来访问(推荐)
(2)也可以使用对象访问

代码案例如下:

public class Demo{
	static int num;
}

public static void main(String[] args){
	Demo.num = 10; //通过类名访问
	Demo demo = new Demo();
	demo.num = 20; //通过对象来访问
}
1.2 基本特点

1、静态属性可以使用类名或者对象来访问
2、静态属性是属于类的,是这个类的所有对象所共享的

1.3 存储位置

存储在内存中的方法区

1.4 静态属性与非静态属性的初始化

要么系统默认赋值,要么人为手动赋值。
初始化时间:
(1)静态属性
类加载到内存中(方法区)的时候,系统会给类中的静态属性做初始化赋默认值,所以在没有创建对象的时候,只要类加载到了内存就可以直接使用类名来访问静态属性
(2)非静态属性
创建对象后,系统自动给对象中的非静态属性做初始化赋默认值,所以对于非静态属性,只有在创建对象后才能通过对象访问

在这里插入图片描述
注意:
1、Demo类,被加载到内存的时候,静态属性num已经完成了默认的初始化赋值操作
2、可以通过类名(Demo.num)来访问,它可以直接找到方法区中存储的静态变量num
3、可以通过对象(demo.num)来访问,引用demo先找到堆区中的对象,再根据对象中存储的Demo.class信息,找到方法区中存储的静态变量num
4、通过上述可知,无论使用类名还是使用对象来访问静态变量num,都是访问的同一个num,但是官方推荐的是使用类名来访问更加合适。

小结:
静态属性是属于类的,只要类加载到内存了,就可以使用类名来访问。
非静态属性是属于对象的,只有创建出对象了,使用对象才可以访问


2、静态方法

2.1 定义

使用static修饰的方法

2.2 静态方法的调用

(1)使用类名调用(推荐)
(2)使用对象来调用
代码演示:

public class Demo{        
public static void test(){    
       
	}    
}
public static void main(String[] args){ 
	Demo.test();//推荐的方式        
	Demo demo = new Demo();    
	demo.test();//可以调用,但是不推荐
	}
注意

1、静态方法中不能调用类中的非静态方法或非静态属性
2、在非静态方法中可以直接访问类中的静态属性和静态方法
3、在构造器中对类中的静态属性做初始化编译时可以通过的,但运行时候可能会出现问题

补充

1、在类加载的时候,JVM会优先给类中的静态属性做初始化,给类中的静态方法分配内存空间。
2、而类中非静态属性的初始化,非静态方法的分配空间,是要等到创建对象之后才会进行的。
3、所以类加载完成之后,就可以直接使用类名访问静态属性和静态方法。
4、所以创建对象之后,才可以使用对象访问非静态属性和调用非静态方法。

??问题??
有如下代码:虽然在构造器中给num赋值为10,但是在访问num的时候,看到的结果却是0

public class Demo {    
	public static int num;    
	public Demo(){        
	num = 10;   
	}
}
public static void main(String[] args){    	
	System.out.println(Demo.num);//输出结果为 0
}

原因:
构造器是在创建对象的时候调用的,而在上面的代码中,我们并没有创建对象,而是直接使用类名访问了这个num属性,那么构造器中的代码也就没有执行,所以最后看到的结果是0。


3、静态代码块

3.1 定义

静态代码块,也叫做静态初始化代码块,它的作用就是给类中的静态属性做初始化的

3.2 静态代码块的执行时刻

类加载的时候自动执行,可以更早的给类中的静态属性,进行初始化赋值操作。并且,静态代码块只会自动被执行一次,因为JVM在一次运行中,对一个类只会加载一次

3.3 关于匿名代码块
3.3.1 作用

给非静态属性做初始化操作。

代码演示如下
public class Demo {    
	public int num;   
	//匿名代码块
	{        
	num = 10;   
	}
}

public static void main(String[] args){    
	Demo demo = new Demo();   
	System.out.println(demo.num);//输出结果为 10
}

类中的构造器,既能给非静态属性进行初始化,又能配合new关键字进行对象的创建,所以匿名代码块使用的场景较少,它能完成的工作,使用构造器也一样可以完成。

3.3.2 匿名代码块的执行时刻

由于匿名代码块没有名字,我们并不能主动调用,它会在创建对象的时候,构造器执行之前,自动执行。并且每次创建对象之前,匿名代码块都会被自动执行

— 题目 ----分析如下代码—

public class Test {
  	public static void main(String[] args) { 
    Zi z = new Zi(); 
  	} 
}

class Fu { 
  	static { 
    	System.out.println("静态代码块Fu"); 
  	}
 	{ 
	    System.out.println("匿名代码块Fu"); 
 	}
	 public Fu() { 
 	  	System.out.println("构造方法Fu"); 
  	} 
}

class Zi extends Fu { 
  	static {
    	System.out.println("静态代码块Zi"); 
  	}
  	{ 
    	System.out.println("匿名代码块Zi"); 
  	}
 	public Zi() { 
    	System.out.println("构造方法Zi"); 
  	} 
}

//结果:
静态代码块Fu
静态代码块Zi
匿名代码块Fu
构造方法Fu
匿名代码块Zi
构造方法Zi

分析:
(1)类加载到内存中的时候,静态代码块就会执行,所以先执行完所有静态代码块,但注意,如果有子父类关系,就先执行父类,再执行子类。所以先执行两个静态代码块,且执行一次。
(2)匿名代码块在创建对象的时候,构造方法之前执行,也是按先父类再子类的顺序,所以先执行父类的匿名代码块,在执行父类中的构造方法,接下来才是子类中的匿名代码块,构造方法。


4、静态导入

定义

在自己的类中,要使用另一个类中的静态属性和静态方法,那么可以进行静态导入,导入完成后,可以直接使用这个类中的静态属性和静态方法,而不用在前面加上类名。

使用静态导入与非静态导入对比
//静态导入
import static java.lang.Math.PI; 
import static java.lang.Math.random; 

public class Demo {    
	public void test(){        
		System.out.println(PI);        					
		System.out.println(random());   
	}
}

//非静态导入
public class Demo {    
	public void test(){        
		System.out.println(Math.PI);
		//访问Math类中的静态属性PI,表示圆周率π        
		System.out.println(Math.random());
		//访问Math类中的静态方法random(),生成随机数   
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值