一:static是什么?其特点为?
- static是修饰符,修饰成员
- static是静态变量
- static修饰的成员被所有对象共享
- static优先于对象的存在,因为static的成员随着类的加载就已经存在了
- static修饰的成员多了一种被调用的方式,可以直接被类名所调用(类名.静态成员)
- static修饰的数据是共享数据,对象中存储的是特有数据
二:成员变量与静态变量的区别
-
两个变量的生命周期不同
-成员变量随着对象的创建而存在,随着对象的消失而释放
-静态变量随着类的加载而存在,随着类的消失而消失 -
两个变量的调用方式不同
-成员变量只能被对象调用
-静态变量可以被对象调用也可以被类名调用 -
两个变量的别名不同
-成员变量也称为实例变量
-静态变量被称为类变量 -
数据存储位置不同
-成员变量数据存储于堆内存的对象中,所以也叫对象的特有数据
-静态变量数据存储在方法区的(共享数据区)静态区,所以也叫对象的共享数据
三:static静态使用的注意事项
-
静态只能访问静态的成员(成员变量,函数)
-非静态能访问非静态,也能访问静态 -
静态方法中不可以使用this或者super关键字----因为没有对象
-
主函数是静态的
四: static编译语句报错原因
class TestStatic2{
int num=4;
public static void main(String [] args){
show();
}
public void show(){
System.out.println(num);
}
}
- 主函数是静态的, 静态无法访问非静态
- 修改语句,在show前加一个static如下
class TestStatic2{
int num=4;
public static void main(String [] args){
show();
}
public static void show(){
System.out.println(num);
}
}
- 还是报错,num属于静态语句中无法调用非静态语句
- 修改方法,在num语句加static如下
class TestStatic2{
static int num=4;//未加static是对象特有数据,加了static是对象的共享数据
public static void main(String [] args){
show();
}
public static void show(){
System.out.println(num);
}
}
- 没有报错
- 但是一般不这么改,正确的改法如下图
class TestStatic2{
int num=4;
public static void main(String [] args){
new TestStatic().show();//用new新建调用方式
}
public void show(){
System.out.println(num);
}
}
五:主函数的特殊之处
public static void main(String[] args){}
- 格式是固定的
- 被虚拟机所识别和调用
-public :权限必须是最大的
-static:被虚拟机调用不需要对象,直接用主函数所属类名调用即可
-void:主函数没有具体返回值(不需要返回值)
-main:函数名,不是关键字,只是虚拟机识别的固定名字
-String[] args:这是主函数的参数列表,是一个数组类型的参数,且元素都为字符串类型
public class TestMain{
public static void main(String[] args){//new String [0]
System.out.println(args);
}
}
-运行显示: [Ljava.lang.String;@6d06d69c
- 解读:[ 表示数组,L表示Long,java.String表示一个包,String代表字符串类型
- 虚拟机调用主函数确实给main方法传递了一个字符串类型的数组实体
- args.length=表示长度为0,虚拟机调用是主函数往里传了new string[0]参数
- 有数组实体,但没有元素
public class TestMain{
public static void main(String[] args){
System.out.println(args);
System.out.println(args.length);
System.out.println(args[0]);//打印0角标的元素,很显然没有
}
}
-
Exception in thread “main” java.lang.ArrayIndexOutOfBoundsException: 0
at TestMain.main(TestMain.java:5) 表示角标越界 -
我可以输出有角标的,在dos命令中,空格一下,然后输别的元素即可,如下
- 以数组的元素进行封装,所以输几个显示几个
public class TestMain{
public static void main(String[] args){
System.out.println(args);
System.out.println(args.length);
System.out.println(args[0]);
for(int x=0;x<args.length;x++){
System.out.println(args[x]);
}
}
}
六:啥时候使用静态变量
- 当分析对象中所具备的成员变量的值都相同,这时这个成员都可以被静态修饰
- 只要数据在对象中都是不同的,就是对象特有的数据,必须存储于对象中,此时是非静态
- 如果相同的数据,对象不需要做修饰,只需要使用即可,不需要存储对象中。–定义成静态的
七:静态函数
- 函数是否用静态修饰,就参考一点,该函数功能是否有访问对象特有的数据
- 简单来说,从源代码看该功能是否需要访问非静态的成员变量,需要-------该功能为非静态,不需要----该功能为静态
- 如果定义非静态,但非静态没有被对象调用,仅创建对象调用非静态没有访问特有数据,该对象的创建是没有意思的
八:静态代码块
- 随着类的加载而执行,而且只执行一次
- 作用:给类进行初始化
class staticCode{
static{
System.out.println("hahahha");
}
void show(){
System.out.println("show run");
}
}
class TestStaticCode{
public static void main(String[] args){
new staticCode().show();
}
}
-因为不访问对象的特有数据不需要创建对象
-所以用类去调用
class staticCode{
static int num;
static{
num=10;
num*=3;
System.out.println("hahahha");
}
staticCode(){}
static void show(){
System.out.println(num);
}
}
class TestStaticCode{
public static void main(String[] args){
//new staticCode().show();
staticCode.show();
}
}
构造代码块
- 给所有函数进行初始化
- 给对应对象进行针对性的初始化
- 静态代码块》构造代码块》构造函数这是执行顺序