2.1 概述
以前我们定义过如下类:
public class Student {
// 成员变量
public String name;
public char sex; // '男' '女'
public int age;
// 无参数构造方法
public Student() {
}
// 有参数构造方法
public Student(String a) {
}
}
我们已经知道面向对象中,存在类和对象的概念,我们在类中定义了一些成员变量,例如name,age,sex ,结果发现这些成员变量,每个对象都存在(因为每个对象都可以访问)。
而像name ,age , sex确实是每个学生对象都应该有的属性,应该属于每个对象。
所以Java中成员(变量和方法)等是存在所属性的,Java是通过static关键字来区分的。static关键字在Java开发非常的重要,对于理解面向对象非常关键。
关于 static
关键字的使用,它可以用来修饰的成员变量和成员方法,被static修饰的成员是属于类的是放在静态区中,没有static修饰的成员变量和方法则是属于对象的。我们上面案例中的成员变量都是没有static修饰的,所以属于每个对象。
2.2 定义格式和使用
static是静态的意思。 static可以修饰成员变量或者修饰方法。
2.2.1 静态变量的引入
有static修饰成员变量,说明这个成员变量是属于类的,这个成员变量称为类变量或者静态成员变量。 直接用 类名访问即可。因为类只有一个,所以静态成员变量在内存区域中也只存在一份。所有的对象都可以共享这个变量。
如何使用呢
例如现在我们需要定义传智全部的学生类,那么这些学生类的对象的老师属性应该都是“石破天”,这个时候我们可以把这个属性定义成static修饰的静态成员变量。
定义格式
修饰符 static 数据类型 变量名 = 初始值;
举例
静态成员变量的访问:
格式:类名.静态变量
2.2.2 静态使用语法
总结
static关键字是什么? static表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量。 什么是静态变量,静态方法? 被static修饰的成员变量,叫静态变量。 被static修饰的成员方法,叫静态方法。 有什么特点? 静态成员不属于对象,但是可以被所有对象共享。 静态成员属于类,也叫类成员,随着类的加载而加载,优先于对象存在。 一般通过类名调用,也可以通过对象名调用,但是不推荐。
2.2.3 静态变量的应用案例
有static修饰成员变量,说明这个成员变量是属于类的,这个成员变量称为类变量或者静态成员变量。 直接用 类名访问即可。因为类只有一个,所以静态成员变量在内存区域中也只存在一份。所有的对象都可以共享这个变量。
学习完static修饰成员变量的基本使用之后,接下来我们学习一下static修饰成员变量在实际工作中的应用。
在实际开发中,如果某个数据只需要一份,且希望能够被共享(访问、修改),则该数据可以定义成类变量来记住。
我们看一个案例
需求:系统启动后,要求用于类可以记住自己创建了多少个用户对象。**
-
第一步:先定义一个
User
类,在用户类中定义一个static修饰的变量,用来表示在线人数; -
第二步:再写一个测试类,再测试类中创建4个User对象,再打印number的值,观察number的值是否再自增。
-
运行上面的代码,查看执行结果是:
系统创建的User对象个数:
4
2.2.4 静态方法应用案例
学习完static修饰方法之后,我们讲一个有关类方法的应用知识,叫做工具类。
如果一个类中的方法全都是静态的,那么这个类中的方法就全都可以被类名直接调用,由于调用起来非常方便,就像一个工具一下,所以把这样的类就叫做工具类。
package com.itheima.static03;
/*
ArrayUtil 数组工具类
里面提供了 操作数组的方法
为什么叫工具类呢?
区别于javabean类的,不表示任何事物。
里面只是定义 操作数组的方法!!
因为主要是来调用方法,所以对象不重要,所以这里方法都是静态的,构造私有的。
工具类特点
1: 构造私有。
2: 方法静态。
3: 见名知意。
*/
public class ArrayUtil {
// 构造私有的目的 不叫别人创建对象
private ArrayUtil(){}
/*
设计方法
提供一个 打印方法 printArr 用于返回整数数组的内容。
一个模板 两个明确
明确参数列表 :
整数数组 int[]
明确返回值类型
String
实现方法:
int[] arr = {1,2,3,4};
通过方法
产出一个字符串 [1,2,3,4]
拼接字符串
*/
public static String printArr(int[] arr){
// 定义一个 初始字符串
String str = "[";
// 循环遍历 进行字符串拼接
for (int i = 0; i < arr.length; i++) {
// arr[i]每个元素
if(i== arr.length-1){//是最后一个元素
str += arr[i];//不要逗号
}else {//不是最后一个元素
str += arr[i]+",";//要逗号
}
}
// 拼接末尾
str += "]";
// 拼接完成再返回
return str;
}
/*
提供一个getAverage 用于返回平均分
求 浮点型数组 的 平均分
明确 返回值 平均分 double
明确 参数 浮点型数组 double[]
*/
public static double getAverage(double[] arr){
// 求和 套路
// 定义求和变量
double sum = 0;
// 遍历 进行累加
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
// 处理 求和变量
double avg = sum/arr.length;
return avg;
}
}
package com.itheima.static03;
import java.util.Arrays;
public class TestDemo {
public static void main(String[] args) {
//测试 printArr方法 将一个整数数组 转换成 字符串
// 定义 整数数组
int[] arr = {9,5,2,7};
//调用 的 工具方法 完成转换
String s = ArrayUtil.printArr(arr);
System.out.println(s);
//测试getAverage 获取平均分方法
double[] arr2 = {98.5,97.5,99.5,0};
double average = ArrayUtil.getAverage(arr2);
System.out.println(average);
//刚刚自己写的工具类---玩一次就行
String s1 = Arrays.toString(arr);
System.out.println(s1);
}
}
总结
类方法有啥应用场景? 可以用来设计工具类。 工具类是什么,有什么好处? 工具类中的方法都是类方法,每个类方法都是用来完成一个功能的。 提高了代码的复用性;调用方便,提高了开发效率。 为什么工具类要用类方法,而不是用实例(普通成员)方法? 实例方法需要创建对象来调用,会浪费内存。 工具类定义时有什么要求? 工具类不需要创建对象, 建议将工具类的构造器私有化
2.2.4 类成员 实例成员辨析
public class People {
// 静态变量
static String name;
// 实例变量
int age ;
public static void show1(){
System.out.println("这是一个静态方法");
}
public void show2(){
System.out.println("这是一个实例方法");
}
}
访问:
package com.itheima.static02;
/*
加入了静态之后
方法和变量访问 可以直接通过类
不用创建对象情况下 完成方法和变量调用。
*/
public class Test {
public static void main(String[] args) {
//静态变量 直接类名调用
People.name = "jackMa";
//静态方法 类名直接调用
People.show1();
// 静态内容 被对象 共享
// People.show2(); 类无法调用实例内容
}
}
2.2.5 static使用注意事项
-
静态方法只能访问静态变量和静态方法
-
非静态方法可以访问静态变量或者静态方法,也可以访问非静态的成员变量和非静态的成员方法
-
静态方法中是没有this关键字
演示--了解目的
package com.itheima.static05;
/*
保证 程序中 有且只有 一个app对象
合理隐藏
1:私有构造(不让外界new)
合理暴露
2:new 出一个对象 在当前类中
定义为私有的静态变量 因为类加载一次 静态变量初始化一次。
3:如何暴露出来
提供get方法---也得是静态
饿汉式
立即加载,当类产生的时候,对象就产生了,不管你用不用对象。
大学食堂
(用于--访问量大的对象。)
懒汉式 --多线程补充
延迟加载,当类产生的时候,不创建对象。需要再创建。
小饭馆
(用于--个性的 访问量小的)
*/
public class App {
private static App app = new App();//实例变量? 静态变量?
// 保证new的事情 做一次 静态变量 随着类的加载而加载 一次
private App(){}
public static App getApp(){
return app;
}
}
package com.itheima.static05;
public class Phone {
public static void main(String[] args) {
//需求 打开 app的时候 只允许在内存中运行一个对象
App a1 = App.getApp();
App a2 = App.getApp();
App a3 = App.getApp();
System.out.println(a1);
System.out.println(a2);
System.out.println(a3);
}
}
2.3 小结
1.当 static
修饰成员变量或者成员方法时,该变量称为静态变量,该方法称为静态方法。该类的每个对象都共享同一个类的静态变量和静态方法。任何对象都可以更改该静态变量的值或者访问静态方法。但是不推荐这种方式去访问。因为静态变量或者静态方法直接通过类名访问即可,完全没有必要用对象去访问。
2.无static修饰的成员变量或者成员方法,称为实例变量,实例方法,实例变量和实例方法必须创建类的对象,然后通过对象来访问。
3.static修饰的成员属于类,会存储在静态区,是随着类的加载而加载的,且只加载一次,所以只有一份,节省内存。存储于一块固定的内存区域(静态区),所以,可以直接被类名调用。它优先于对象存在,所以,可以被所有对象共享。
4.无static修饰的成员,是属于对象,对象有多少个,他们就会出现多少份。所以必须由对象调用。