什么时候成员变量声明为实例变量呢?
所有对象都具有这个属性,但是这个属性的值会随着对象的变化而发生变化【不同对象的这个属性值不同】
什么时候成员变量声明为静态变量呢?
所有对象都具有这个属性,并且所有对象的这属性的值是一样的,建议定为静态变量,节省内存的开销。
静态变量在类加载的时候会初始化,内存在方法区里开辟。访问的时候不需要创建对象,直接使用”类名.静态变量名“访问
/**
* “中国人”类
*
*/
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关键字详解