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语句
}
实例代码段在,对象初始化的时候执行,在构造方法之前执行,可以有多句
在实例代码中可以对静态变量和实例变量赋值
在实例代码中可以调用静态方法和实例方法