文章目录
十一.static
11.1static静态变量
1.static 表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量;
2.被static修饰的成员变量叫做静态变量;被static修饰的成员方法叫静态方法。
3.静态变量在堆中的静态区
4.静态变量的特点:
-
被该类所有的对象共享
-
不属于对象,属于类
-
随着类的加载而加载,优先于对象存在(加载).
-
(类内部,可在任何方法内直接访问静态变量)
(其他类中,可以直接通过类名访问)
-
在内存中只有一个拷贝
5.实例变量
没有被static修饰的变量每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响
6.静态变量调用方式:
-
类名调用
-
对象名调用
public class Student {
//属性:姓名 年龄 性别
//新增:老师的姓名
private String name;
private int age;
private String gender;
public static String teacherName;//定义为静态变量
public Student() {}
public Student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() { return name;}
public void setName(String name) { this.name = name;}
public int getAge() { return age;}
public void setAge(int age) { this.age = age;}
public String getGender() { return gender;}
public void setGender(String gender) {this.gender = gender;}
//行为
public void study() {
System.out.println(name + "正在学习");
}
public void show() {
System.out.println(name + ", " + age + ", " + gender + ", " + teacherName);
}
}
public class StudentTest {
public static void main(String[] args) {
//类名调用静态变量,类中所有对象共享
Student.teacherName = "小孔老师";
//1.创建第一个学生对象
Student s1 = new Student();
s1.setName("张三");
s1.setAge(23);
s1.setGender("男");
//s1.teacherName = "大孔老师";//对象调用静态变量
s1.study();//张三正在学习
s1.show();// 张三,23 ,男,小孔老师
//2.创建第二个学生对象
Student s2 = new Student();
s2.setName("李四");
s2.setAge(24);
s2.setGender("女");
//s2.teacherName = "大孔老师";//对象调用静态变量
s2.study();// 李四正在学习
s2.show();// 李四,24 ,女,小孔老师
}
11.2 static 内存图
静态变量在堆中的静态区
(图片来自B站)
当对象s2的name 、age 没有赋值时,输出的是默认值。
每new一次会在堆中开辟一小块空间。
(图片来自B站Java视频)
11.3 static-静态方法
被static 修饰的成员方法,叫静态方法。
特点:
-
多用在测试类中和工具类中
-
JavaBean类中很少会用
调用方式:
-
类名调用
-
对象名调用
11.3.1工具类
帮助我们做一些事情的,但是不描述任何事物的类。
工具类不需要创建对象。
工具类注意事项:
- 类名要见名知意
- 私有化构造方法:不让外界创建它的对象
- 方法定义为静态
11.3.1.1案列1
定义工具类方法:
1.用户返回整数数组的内容,返回的字符串格式如[1,2,3],只考虑一维数组
2.提供一个工具方法getAverage用户返回平均值,只考虑浮点型,一维数组
定义测试类,调用工具类里的工具方法,并返回结果
public class ArrayUtil {
// 私有化构造方法
// 目的:为了不让外界创捷它的对象
private ArrayUtil (){}
// 其他方法定义为静态
// 目的:方便外界调用
// 定义工具类方法:
// 1.用户返回整数数组的内容,返回的字符串格式如[1,2,3],只考虑一维数组
public static String printArr(int[] arr){
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length-1){
sb.append(arr[i]);
}else {
sb.append(arr[i] + ",");
}
}
sb.append("]");
return sb.toString();
}
// 2.提供一个工具方法getAverage用户返回平均值,只考虑浮点型,一维数组
public static double getAverage(double[] arr){
double sum = 0;
for (int i = 0; i < arr.length; i++) {
sum = sum +arr[i];
}
return sum/arr.length;
}
public class ArrayUtilTest {
public static void main(String[] args) {
// 定义测试类,调用工具类里的工具方法,并返回结果
int[] arr1 = {1,2,3};
// 用 类名调用
String s = ArrayUtil.printArr(arr1);
System.out.println(s);
double[] arr2 = {5,5,5,5};
double average = ArrayUtil.getAverage(arr2);
System.out.println("平均分:"+average);
}
}
11.3.1.2 案例2
定义学生工具类
-
需求:定义一个集合,用于存储3个学生对象
-
学生类的属性为:name /age/gender
-
定义一个工具类,用于获取集合中最大学生的年龄
// 标准学生JavaBean类
public class Student {
private String name;
private int age;
private String gender;
public Student() {}
public Student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {return name;}
public void setName(String name) { this.name = name;}
public int getAge() { return age;}
public void setAge(int age) { this.age = age; }
public String getGender() { return gender; }
public void setGender(String gender) {
this.gender = gender;
}
}
// 工具类 求最大年龄
import java.util.ArrayList;
public class StudentUtil {
// 私有化构造方法
private StudentUtil(){}
// 定义一个求最大年龄的方法
public static int getAge(ArrayList<Student> list){
// 初始默认集合中的第一个元素对象的年龄最大
int ageMax = list.get(0).getAge();
for (int i = 0; i < list.size(); i++) {
//i 索引 list.get(i)元素/学生对象 还需要getAge获取到年龄之后再进行比较
int tempAge = list.get(i).getAge();
if (tempAge>ageMax){
ageMax = tempAge;
}
}
return ageMax;
}
}
//测试类
import java.util.ArrayList;
public class StudentTest {
public static void main(String[] args) {
// 创建集合
ArrayList<Student> list = new ArrayList<>();
// 创建对象并赋值
Student s1 = new Student("小孔",18,"男");
Student s2 = new Student("大聪明",19,"女");
Student s3 = new Student("小聪明",120,"女");
// 将学生对象添加到集合中
list.add(s1);
list.add(s2);
list.add(s3);
//调用工具类中的方法
int ageMaxEnd = StudentUtil.getAge(list);
System.out.print("最大年龄为:"+ageMaxEnd);
}
}
11.4静态代码块
静态代码块:
格式:static{ }
特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发,只执行一次
使用场景:在类加载时,做一些数据初始化的时候使用。
11.5 static 注意事项
-
静态方法只能访问静态变量和静态方法
(即 静态方法不能直接访问所属类的实例变量和实例方法)
-
非静态方法可以访问静态变量或静态方法,也可以访问非静态的成员变量和非静态的成员方法。(即 非静态方法可以访问所有)
-
静态方法中没有this关键字
-
在实例方法里不可以定义static变量,但是可以访问静态变量
总结:
-
静态方法中没有this关键字
静态是所有对象共享的,所以在使用时跟具体某个对象的调用无关,所以没有this。
-
静态方法中,只能访问静态
如果在静态方法中,访问非静态成员变量,就会出现不知道访问该变量是哪个对象的成员变量;如果要访问指定对象的变量,需要加上this关键字,但在静态方法中没有this关键字。因此不能访问非静态成员变量。
-
非静态方法中可以访问所有
非静态的东西跟对象有关,静态变量和静态方法的调用都可以用对象名调用,所以用对象名方式的调用可以访问静态和非静态。
**在非静态成员方法的形参当中有个隐藏的 this
.**如下代码所示:
//上述输出结果为:
stringstaticdemo.demo3.Student@1540e19d
this:stringstaticdemo.demo3.Student@1540e19d
大聪明.18.小孔
这是show2
========
stringstaticdemo.demo3.Student@677327b6
this:stringstaticdemo.demo3.Student@677327b6
小聪明.19.小孔
这是show2
11.6重识main
-
public
:被jvm调用,访问权限足够大 -
static
:被jvm调用,不能创建对象,直接类名访问。因为main 方法是静态,所以测试类中其他方法也需要是静态的
-
void
:被jvm调用,不需要给jvm返回值 -
main
:一个通用的名称,虽不是关键字,但可以被jvm识别