Java 从零开始 4.8 static关键字

1.static + 变量名

static 可以用来修饰变量。

在之前我们讲过变量分为,成员变量和局部变量。

而实际上成员变量又分为,实例变量和静态变量。

被static修饰的成员变量称为静态变量或类变量

没有被static修饰的成员变量称为实例变量

下面说明成员变量和实例变量的区别:

比如说现在某地一中希望建立一个学生的数据库,要求存储每个学生的姓名、年龄、学校。

我们可以这么写代码:
首先是Student类:
 

public class Student {
    String name;
    int age;
    String school;

    public Student(){}
    public Student(String name, int age , String school)
    {
        this.name = name;
        this.age = age;
        this.school = school;
    }
    public void Student_print()
    {
        System.out.println(this.name);
        System.out.println(this.age);
        System.out.println(this.school);
    }
}

然后我们在test中将学生的信息存进去:

public class test
{
	public static void main(String[] args)
	{
		Student stu1 = new Student( "李华", 10,  "一中");
		Student stu2 = new Student( "王五", 11,  "一中");
		Student stu3 = new Student( "李四", 10,  "一中");
		Student stu4 = new Student( "小红", 11,  "一中");
		Student stu5 = new Student( "小明", 10,  "一中");

		stu1.Student_print();
		stu2.Student_print();
		stu3.Student_print();
		stu4.Student_print();
		stu5.Student_print();
	}
}
 

结果如下:

 可以看到成功实现了功能。

但是这里有一个问题,每个学生的学校信息都是一中,而我们每一个对象都分配了一个内存去存储学校信息,而这些学校信息都是一样,这就造成了内存的浪费。

如果我们这样修改:

public class Student {
    String name;
    int age;
    static String school = "一中";

    public Student(){}

    /**
     * 
     * @param name
     * @param age
     * @param school
     */
    public Student(String name, int age)
    {
        this.name = name;
        this.age = age;
    }
    public void Student_print()
    {
        System.out.println(this.name);
        System.out.println(this.age);
        System.out.println(school);
    }
}
public class test
{
	public static void main(String[] args)
	{
		Student stu1 = new Student( "李华", 10);
		Student stu2 = new Student( "王五", 11);
		Student stu3 = new Student( "李四", 10);
		Student stu4 = new Student( "小红", 11);
		Student stu5 = new Student( "小明", 10);

		stu1.Student_print();
		stu2.Student_print();
		stu3.Student_print();
		stu4.Student_print();
		stu5.Student_print();
	}
}
 

同样可以实现功能,并且所有的对象共用一个学校信息,节省了空间。

而从上面的例子里,我们还可以看到一些不同。

实例变量是基于对象的,也就是说,一定是要先有某个对象,然后才有的实例变量。

在上述例子中,我们先有了对象stu1,然后给stu1的name、age等实例变量赋值

而修饰为static的静态变量school则是在我们声明对象stu1之前就已经完成了分配内存和赋值

我们再用一个例子更进一步的说明这个问题:

public class test
{
	public static void main(String[] args)
	{
		Student stu1 = new Student( "李华", 10);
		stu1.Student_print();
		Student stu2 = new Student( "王五", 11);
		stu2.school = "二中";
		stu1.Student_print();

	}
}
 

结果如下:

 可以看到,我们明明是对stu2.school进行了修改,但是stu1的school也变了,这就说明用static修饰的静态变量是所有对象共有的。

而且我们可以看到下图中stu2.school下面花了条波浪线,并且报了一个警告

 这是编译器告诉我们,这个写法是不规范的,但是可以允许。

而标准的写法应该改成

Student.school = "二中";

这里也是实例变量和静态变量的一个区别:

实例变量的调用    引用名.变量名

静态变量的调用     类名.变量名(也可以使用引用名.变量名,但是不规范,会被警告)

2.static + 方法名

static 可以修饰方法

被static修饰的方法被称为静态方法

不被static修饰的方法被称为实例方法

静态方法和实例方法的区别:
(1)调用不同

实例方法的调用  引用名.方法名

静态方法的调用  类名.方法名

(2)实例方法必须先有一个对象,然后才可以调用,而静态方法可以直接调用。

举个例子:

新建一个add类:

定义两个方法一个用了static,一个没有

public class add {
    public int add_num1(int i1, int i2)
    {       
        return i1 + i2;
    }
    public static int add_num2(int i1, int i2)
    {
        return i1+i2;
    }
    
}

   测试一下:
例1:

public class test
{
	public static void main(String[] args)
	{
		System.out.println(add.add_num2(3, 4));

	}
}
 

结果如下:

例2:

public class test
{
	public static void main(String[] args)
	{
		System.out.println(add.add_num1(3, 4));

	}
}
 

 结果如下:

 可以看到使用static修饰的静态方法,可以直接调用,而实例方法不行。

例3:

public class test
{
	public static void main(String[] args)
	{
		add add1 = new add();
		System.out.println(add1.add_num1(3, 4));

	}
}
 

结果如下:

可以看到实例变量的正确调用方法是先声明一个对象,然后使用引用名.方法名的方式来调用。

例4:

public class test
{
	public static void main(String[] args)
	{
		add add1 = new add();
		System.out.println(add1.add_num2(3, 4));

	}
}
 

 结果如下:

可以看到静态方法同样可以使用引用名.方法名来调用

只是:

可以看到编译器报了一个警告,说明这个写法是不规范的。

3. static + 代码段

(1)static 修饰的代码段称为静态代码段

写法

    static{
        //java语句
    }

静态代码段在类加载的时候被执行,可以有多句,只执行一次。

在静态代码段中,可以对静态变量进行赋值,而不能对实例变量进行赋值。

在静态代码段中,可以调用静态方法,而不能调用实例方法

(2)不被static修饰的代码段称为实例代码段

写法

    {
        //java语句
    }

 实例代码段在,对象初始化的时候执行,在构造方法之前执行,可以有多句

在实例代码中可以对静态变量和实例变量赋值

在实例代码中可以调用静态方法和实例方法

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值