Java入门——static关键字详解

什么时候成员变量声明为实例变量呢?

所有对象都具有这个属性,但是这个属性的值会随着对象的变化而发生变化【不同对象的这个属性值不同】

什么时候成员变量声明为静态变量呢?

所有对象都具有这个属性,并且所有对象的这属性的值是一样的,建议定为静态变量,节省内存的开销。

静态变量在类加载的时候会初始化,内存在方法区里开辟。访问的时候不需要创建对象,直接使用”类名.静态变量名“访问

/**
 * “中国人”类
 *
 */
public class Chinese {

	//身份证号【每一个中国人对象身份证号不一样】
	//实例变量
	String id;
	
	//姓名【每一个对象的姓名不同】
	//实例变量
	String name;
	
	//国籍【每一个对象由于都是由”Chinese类“实例化的所以每一个中国人的国籍都是”中国“】
	//无论通过Chinese类实例化多少个java对象,这些java对象的国籍都是“中国”
	//实例变量【实例变量是一个java对象就有一份,100个对象就有100个country】,分析这种设计方式的缺点。
	//实例变量存在堆内存,构造方法执行时初始化
	String country;
	
	//构造无参数构造方法
	public Chinese() {
		
	}
	
	//构造有参数方法
	public Chinese(String id,String name,String country) {
		this.id=id;
		this.name=name;
		this.country=country;
	}
	
	
}
public class ChineseTest {

	public static void main(String[] args) {

		//创建一个Chinese对象
		Chinese zhangsan=new Chinese("1","张三","中国");
		System.out.println(zhangsan.id+","+zhangsan.name+","+zhangsan.country);
		
		//创建一个Chinese对象
		Chinese lisi=new Chinese("2","李四","中国");
		System.out.println(lisi.id+","+lisi.name+","+lisi.country);
		
		//创建一个Chinese对象
		Chinese wangwu=new Chinese("3","王五","中国");
		System.out.println(wangwu.id+","+wangwu.name+","+wangwu.country);
		
	}

}

声明为实例变量的内存分析图
在这里插入图片描述

public class Chinese {

	//身份证号【每一个中国人对象身份证号不一样】
	//实例变量
	String id;
	
	//姓名【每一个对象的姓名不同】
	//实例变量
	String name;
	
	//国籍
	//更改为静态变量
	static String country="中国";
	
	//构造无参数构造方法
	public Chinese() {
		
	}
	
	//构造有参数方法
	public Chinese(String id,String name) {
		this.id=id;
		this.name=name;
	}
	
	
}


public class ChineseTest {

	public static void main(String[] args) {

		//创建一个Chinese对象
		Chinese zhangsan=new Chinese("1","张三");
		System.out.println(zhangsan.id+","+zhangsan.name+","+Chinese.country);
		
		//创建一个Chinese对象
		Chinese lisi=new Chinese("2","李四");
		System.out.println(lisi.id+","+lisi.name+","+Chinese.country);
		
		//创建一个Chinese对象
		Chinese wangwu=new Chinese("3","王五");
		System.out.println(wangwu.id+","+wangwu.name+","+Chinese.country);
		
		System.out.println(Chinese.country);
		
		//访问张三的国籍
		System.out.println(zhangsan.country);//警告,但是可以访问。
		
		zhangsan=null;
		System.out.println(zhangsan.country);//编译通过,并未出现空指针异常,说明访问变量时并没有对象的参与。
		//即使写了“引用.”,实际上访问的还是“Chinese.country”
		
		//所有static的都可以用类名.也能用引用.[后者不推荐]
		
		//System.out.println(country);//注意哦,编译报错,country是另一个类中的静态变量
	}

}

使用静态变量的内存分析图
在这里插入图片描述
关于Java中static关键字的总结:
1 static英语单词翻译成”静态的“

2 static修饰的方法是静态方法

3 static修饰的变量是静态变量

4 所有带有static的元素都是静态的,都可以使用”类名.”的方式去访问,当然也可以采用“引用.”的方式去访问【不推荐,建议使用类名.】

5 static修饰的元素都是类级别的特征,和对象无关

可以使用static关键字来定义“静态代码块”

  • 语法格式:
    static{

    java语句;

    }

  • 静态代码块在类加载的时候执行,并且只执行一次

  • 静态代码块在一个类中可以编写多个,并且遵循自上而下的顺序依次执行

  • 静态代码块的作用是什么?怎么用?用在哪?什么时候用?

    这当然和具体的业务需求有关,例如项目中要求在类加载的时刻/时机执行代码完成的日志记录。那么这段记录日志的代码就可以编写到静态代码块中,完成日志记录

    静态代码块是为程序员准备的一个特殊时刻,这个特殊时刻被称为类加载时刻。若希望在此时执行一段特殊的程序,这段程序可以放到静态代码块当中。

  • 通常在静态代码块中完成预备工作,先完成数据的准备工作,例如:初始化连接池,解析XML配置文件等

public class StaticTest01 {

	static {
		System.out.println("类加载 -- >1");
	}
	
	static {
		System.out.println("类加载 -- >2");
	}
	
	static {
		System.out.println("类加载 -- >3");
	}
	
	public static void main(String[] args) {

		System.out.println("main begin");
	}

}

实例语句块/代码块【了解内容,使用的非常少】

  • 1.实例代码块可以编写多个,也是遵循自上而下依次执行的顺序
  • 2.实例代码块在构造方法执行前执行,构造方法执行一次,实例代码块对应执行一次
  • 3.实例代码块也是java语言当中为程序员准备的一个特殊的时机,这个特殊时机被称为:对象初始化时机
public class Test {

	//构造方法
	public Test() {
		System.out.println("Test类的缺省构造器执行!");
	}
	
	//实例代码块
	{
		System.out.println(1);
	}
	
	//实例代码块
	{
		System.out.println(2);
	}
	
	//实例代码块
	{
		System.out.println(3);
	}
	
	public static void main(String[] args) {

		System.out.println("main begin!");
		
		new Test();
		
		new Test();
		
		
	}

}

方法在什么时候定义静态方法?

  • 方法描述的是动作,当所有的对象执行这个动作的时候,最终产生的影响是一样的,那么这个动作已经不再属于某一个对象的动作了,可以将这个动作提升为类级别的动作,模板级别的动作

  • 静态方法中无法直接访问实例变量和实例方法。(因为不存在this,所以只能创建对象,用引用.)

  • 大多数方法都定义为实例方法,一般一个行为或一个动作在发生时,都需要对象的参与,但是也有例外,例如:大多数“工具类”中的方法都是静态方法,因为工具类就是方便编程,为了方便方法的调用,自然不需要new对象是最好的

public class StaticTest {

	//实例变量
	int i=100;
	
	//实例方法
	public void doSome() {
		
	}
	
	//静态方法【静态上下文】
	public static void main(String[] args) {

		//System.out.println(i);
		//doSome();
		
		StaticTest st=new StaticTest();
		System.out.println(st.i);
		st.doSome();
		
	}

}

public class MainTest {

	public static void main(String[] args) {

		//构成方法重载
		System.out.println("Hello!");
		
		main(10);
		
		main("Hello World!");
		
		
	}

	public static void main(int i) {
		System.out.println(i);
	}
	
	public static void main(String args) {
		System.out.println(args);
	}

}

总结:

    class 类名{

	静态代码块;//类加载的时候执行,main方法之前,执行一次
	实例代码块;//main方法之后,构造方法之前执行,执行次数与构造方法相同

	静态变量;//类加载时初始化,通过类名.访问
	实例变量;//构造方法执行的时候初始化,通过引用.访问

	构造方法;//用来创建对象,通过new 调用

	静态方法;//类名.的方式调用
	实例方法;//引用.的方式调用


	}

下一篇:this关键字详解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值