【Java之旅】6.static关键字
6.1 static关键字
①意思
static意为静态的,用它来修饰成员变量和成员方法,在类加载阶段,这些被修饰的成员变量和成员方法,将会被载如JVM中的方法区内存空间中。
静态变量只有一个,被类所拥有,所有的对象都共享这个静态变量,而实例对象与具体对象有关。
如果有一个类,我们希望所有创建这个类型的对象的属性的值都是一样的,并且不对他进行修改,那么如果我们每创建一个新的对象,就会去重复
创建这个属性的内存空间,这样做会很浪费内存空间。
但如果给这个类中的某个属性前用static修饰,就可以让这个属性变量在类加载阶段就被加载完毕,并且对其赋值**,**
这个变量就是静态变量,可以被所有这个类型的对象共用,
②举例
我们来定义一个Rainbowman类(名字乱取的)
我们要输出这个类里面角色等级 姓名 地区三个属性;
这里我有些地方用到了this关键字,这个稍后再进行解释。在这里只要把他理解为给他对象引用名赋值。
public class StaticTest
{
public static void main(String[] args)
{
Rainbowman buck = new Rainbowman();
Rainbowman ash = new Rainbowman(167,"kupurk","China");
buck.setLevel(216);
buck.setName("Mo__");
buck.setArea("China");
System.out.println(buck);
System.out.println(ash);
}
}
class Rainbowman
{
private int level;
private String name;
//private static String area="China";
private String area;
public Rainbowman()//构造方法重载
{
}
public Rainbowman(int level,String name,String area)//构造方法重载
{
this.level=level;
this.name=name;
this.area=area;
}
public void setArea(String area)
{
this.area=area;
}
public void setLevel(int level)
{
this.level = level;
}
public int getLevel()
{
return level;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public String toString()
{
return "[" + level +"," + name +","+ area + "]";
}
}
输出结果为
我们如果在main方法中,对buck的对象的area名进行改动
public class StaticTest
{
public static void main(String[] args)
{
Rainbowman buck = new Rainbowman();
Rainbowman ash = new Rainbowman(167,"kupurk","China");
buck.setLevel(216);
buck.setName("Mo__");
//buck.setArea("China");
buck.setArea("Earth");//将China修改为Earth
System.out.println(buck);
System.out.println(ash);
}
}
/*
输出结果:
[216,Mo__,Earth]
[167,kupurk,China]
*/
我们可以发现修改了buck成员的area并不会对ash成员的area造成影响,也就是说
这两个area的字符串所存放的空间并不是同一个空间
如果类的成员一多,那么这样存储数据特别占内存空间,所以对于这种平时不会去修改的成员属性
我们可以用static进行修饰
public class StaticTest
{
public static void main(String[] args)
{
Rainbowman buck = new Rainbowman();
Rainbowman ash = new Rainbowman(167,"kupurk","China");
buck.setLevel(216);
buck.setName("Mo__");
//buck.setArea("Earth");
//没有对buck的arae属性分配值
System.out.println(buck);
System.out.println(ash);
}
}
class Rainbowman
{
private int level;
private String name;
private static String area="China";
//private String area;
public Rainbowman()//构造方法重载
{
;
}
public Rainbowman(int level,String name,String area)//构造方法重载
{
this.level=level;
this.name=name;
this.area=area;
}
public void setArea(String area)
{
this.area=area;
}
public void setLevel(int level)
{
this.level = level;
}
public int getLevel()
{
return level;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public String toString()
{
return "[" + level +"," + name +","+ area + "]";
}
}
/*
输出结果为
[216,Mo__,China]
[167,kupurk,China]
*/
还没有对buck的area进行赋值,他输出来的area名本因为null但却被赋上了China的值
我们如果修改一下buck的area值
public class StaticTest
{
public static void main(String[] args)
{
Rainbowman buck = new Rainbowman();
Rainbowman ash = new Rainbowman(167,"kupurk","China");
buck.setLevel(216);
buck.setName("Mo__");
buck.setArea("Earth");//将area赋为Earth
System.out.println(buck);
System.out.println(ash);
}
}
运行后得到结果
[216,Mo__,Earth]
[167,kupurk,Earth]
我们明明只对了buck的属性做出了改变,为甚么ash的属性也会发生改变呢??
种种迹象表明,buck和ash的area 指向了同一块内存空间
所以我们对其中一个成员的属性进行修改,另一个成员的属性也会被进行修改
所以static关键字修饰的变量所作用的范围,不仅仅只局限于对象,而是对于整个类而言的
所以我们可以用 “类名.”的方式访问
例如上述例子可以改成
public class StaticTest
{
public static void main(String[] args)
{
Rainbowman buck = new Rainbowman();
Rainbowman ash = new Rainbowman(167,"kupurk","China");
buck.setLevel(216);
buck.setName("Mo__");
//buck.setArea("Earth");//引用调用
Rainbowman.setArea("Earth");//类名调用
System.out.println(buck);
System.out.println(ash);
}
}
但是这样运行,程序会报错
/*
E:\工具\Markdown\输出\EditPlus_out\Classname\Test>javac StaticTest.java
StaticTest.java:10: 错误: 无法从静态上下文中引用非静态 方法 setArea(String)
Rainbowman.setArea("Earth");
^
1 个错误
*/
无法找到静态方法,说明我们不能通过这样的方法去修改静态变量的属性
所以我们就需要对给Area赋值的方法用static关键字进行修饰
public static void setArea(String area)
{
this.area=area;
}
/*
不过这么写,系统却还是报错了
E:\工具\Markdown\输出\EditPlus_out\Classname\Test>javac StaticTest.java
StaticTest.java:32: 错误: 无法从静态上下文中引用非静态 变量 this
this.area=area;
^
1 个错误
*/
他说找不到非静态变量this,okok我们先在在这mark一下,先不管这个错误
我们把这个错误,拉到下回this关键字再说。
我们换一个写法
public static void setArea(String sarea)
{
area=sarea;
}
/*
这回倒是终于成功输出了
[216,Mo__,Earth]
[167,kupurk,Earth]
我们成功的用static关键字修饰过的方法对静态的变量进行了修改
将China改为了Earth
*/
③总结
从上我们的出几个结论
static关键字可以用于修饰成员变量和方法
static修饰的变量叫做静态变量,静态变量只会在类加载阶段在方法去内存空间中进行一次赋初值,为该类所有成员共同享有
static修饰的方法叫做静态方法,只有用static修饰的方法才能用“类名.”的方式去对静态变量做处理
静态的东西与对象无关, 它是类级别的概念。