【Java之旅】6.static关键字

【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修饰的方法才能用“类名.”的方式去对静态变量做处理

静态的东西与对象无关, 它是类级别的概念。

猜你喜欢

转载自blog.csdn.net/u014568597/article/details/113155454