在熟悉的事物中循环
新年快乐!学习继续~
2024年加油!
——24.2.12
模块九重点
1.会定义静态成员以及会调用静态成员
2.会使用可变参数(会给可变参数传参)
3.会二分查找(熟练)
4.会冒泡排序(熟练)
5.Debug的使用
一、static关键字
1.static关键字的介绍以及基本使用
1.概述:static是一个静态关键字
2.使用:
a.可以修饰一个成员变量:
static 数据类型 变量名
b.也可以修饰一个方法:
修饰符 static 返回值类型 方法名(形参){
方法体
return 结果
}
3.调用静态成员(简单)
类名直接调用(不属于静态成员,不用new对象,直接类名.静态成员 进行调用)
4.静态成员特点:
a.静态成员属于类成员,不属于对象(非静态的成员属于对象成员,非静态成员需要先new对象再.进行调用),先有类再有对象,所以先有静态成员,再有非静态成员
b.静态成员会随着类的加载而加载
c.静态成员优先于非静态成员存在在内存中
d.凡是根据静态成员所在的类创建出来的对象,都可以共享这个静态成员
2.static关键字的使用
只需要给static修饰的类对象赋值一次,就会将所有的都进行修改赋值
静态成员推荐使用类名. ,非静态成员推荐使用对象.
可以通过静态关键字修饰classroom,然后直接给个值,s1,s2的classroom都不需要单独维护,因为s1,s2的classroom可以共享static修饰的静态classroom
package S9ObjectOriented01;
public class Student {
String name;
int age;
static String classRoom;
public static void main(String[] args) {
Student student1 = new Student();
student1.name = "郭靖";
student1.age = 28;
student1.classRoom = "111";
Student student2 = new Student();
student2.name = "黄蓉";
student2.age = 26;
student2.classRoom = "111";
Student.classRoom = "114";
System.out.println("s1的classroom:"+student1.classRoom);
System.out.println("s2的classroom:"+student2.classRoom);
}
}
3.static成员的内存说明
静态成员保存在静态域中,静态域在jdk6时期放在方法区中,jdk版本的更新主要针对于内存优化,从JDK7开始,静态域开始在堆内存中出现,原因是堆内存对无用数据回收效率很高,可以更好的回收数据,JDK8时,方法区又称(元空间),静态域还是在堆内存中出现
堆内存对无用数据回收效率很高,可以及时回收静态成员,为保证能够及时回收及时释放内存
调用成员,类就会加载,方法会出现在静态区的堆中,所有对象都会共享静态区内的数据,不同对象都可以共享静态成员
4.static成员的访问特点
1.在静态方法中能直接访问非静态成员吗?
(静态方法是先产生的,非静态成员是后产生的),静态成员随类调用产生 非静态成员随对象产生而产生
无法访问 需要先new对象来调用
2.在非静态方法中能直接访问静态成员吗?
能直接访问,但是要观察是否在同一个类中
a.同类:
直接调用
类名调用
b.不同类:
类名调用
3.在静态方法中能直接访问静态成员吗?
a.同类:
直接调用
类名调用
b.不同类:
类名调用
4.在非静态方法中能直接访问非静态成员吗?
a.同类:
直接调用
new对象调用
b.不同类:
new对象调用
总结:
①不管在不在同一个类中,非静态成员都可以new对象调用
②不管在不在同一个类中,静态成员都可以类名调用
package S10ObjectOriented02;
public class Demo86ObejectPerson {
public void eat(){
System.out.println("人要吃饭");
}
public static void drink(){
System.out.println("人要喝水");
}
}
package S10ObjectOriented02;
public class Demo87ObjectOriented02Test {
public static void main(String[] args) {
// 静态成员中访问非静态成员 静态成员先出生
// 要想访问后出生的非静态成员,必须要先new一个对象
Demo87ObjectOriented02Test Test = new Demo87ObjectOriented02Test();
Test.method03();
Demo86ObejectPerson person = new Demo86ObejectPerson();
person.eat();
}
public static void method01(){
// 静态方法中能直接访问静态成员,同类中:①直接调用 ②类名调用 不同类:类名调用
method02();
Demo86ObejectPerson.drink();
}
public static void method02(){
}
public void method03(){
// 非静态成员可以访问静态成员,具体如何访问看在不在同类中
// 同类中非静态成员访问静态成员
method01();
Demo87ObjectOriented02Test.method01();
// 不同类中非静态成员访问静态成员
// 静态成员推荐使用 类名. 调用
Demo86ObejectPerson.drink();
// new对象后来调用
Demo86ObejectPerson person = new Demo86ObejectPerson();
person.drink();
}
public void method04(){
// 非静态方法中能直接访问非静态成员:能 同类:①直接调用 ②new对象调用
method03();
new Demo87ObjectOriented02Test().method03();
// 非静态方法中能直接访问非静态成员:能 不同类:new对象调用
new Demo86ObejectPerson().eat();
}
}
5.static_静态成员在开发中的使用场景
问题1:
既然static成员那么好使(类名直接调用),那么我们在实际开发中,能不能将所有的成员都定义成静态的呢?
不能 原因:由于静态成员会随着类的加载而加载,如果将所有的成员都变成静态的,那么类一加载,静态成员都会进内存,会大量占用内存空间
问题2:
那么静态成员都啥时候定义呢?
一般情况下,我们在抽取工具类的时候可以将工具类中的所有成员都定义成静态的问题3:
啥时候定义工具类?
比如我们在写代码的过程中,发现有的功能在反复实现,代码一样,功能一样,此时就可以抽取出来,形成工具类,构造方法用private修饰,工具类中的成员都是静态的,静态成员都是类名调用,不需要new对象,所以工具类中的构造方法都是用private修饰的
Test01
package S11Staticulties;
public class Test01 {
public static void main(String[] args) {
//要求实现获取数组最大值
int[] arr = {5,3,4,6,7,54,8};
int max0 = Demo88ArrayUtils.getMax(arr);
System.out.println("max0 =" + max0);
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if(max < arr[i]){
max = arr[i];
}
}
System.out.print("max = " + max);
}
}
Test02
package S11Staticulties;
public class Test02 {
public static void main(String[] args) {
//要求实现获取数组最大值
int[] arr = {5, 4, 6, 7, 9, 18};
int max0 =Demo88ArrayUtils.getMax(arr);
System.out.println("max0 = " + max0);
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
System.out.print(max+" ");
}
}
}
ArrayUtils
package S11Staticulties;
import S17StudentManageSystemProgram.ArrayUtils;
import java.lang.reflect.Array;
public class Demo88ArrayUtils {
/*
构造方法用 private 修饰
工具类中的成员都是静态的,静态成员都是类名调用,不需要new对象
所以工具类中的构造方法都是用private修饰
如果构造方法被private修饰,那么在别的类中,就不能利用构造方法new对象
*/
private Demo88ArrayUtils(){
}
// 定义一个方法,实现获取int数组最大值,静态成员最好使
public static int getMax(int[] arr){
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if(max<arr[i]){
max = arr[i];
}
}
return max;
}
}
二、可变参数(近似于简易数组)
1.需求:
定义一个方法,实现n个整数相加
2.分析:
方法 参数 位置,只明确了参数的类型,但是不明确参数的个数,此时就可以定义为可变参数
1.介绍和基本使用
1.定义格式:
数据类型…变量名
2.注意:
a、可变参数的本质是一个数组
b、参数位置不能连续写多个可变参数,而且当可变参数和其他普通参数一起使用时,可变参数需要一起放到参数列表最后
2.可变参数的练习
练习1
返回n个字符串拼接结果,如果没有传入字符串,那么返回空字符串""
package S12ChangeParameter;
// 需求一:返回n个字符串拼接结果,如果没有传入字符串,那么返回空字符串"
public class Demo90Var02Practice01 {
public static void main(String[] args) {
String result = concat("一切都会好的",",","我一直相信");
System.out.println("result="+result);
}
// 参数为可变参数函数
public static String concat(String...s){
String str = "";
for (int i = 0; i < s.length; i++) {
str+=s[i];
}
return str;
}
}
练习2
n个字符串进行拼接,每一个字符串之间使用某字符进行分割,如果没有传入字符串,那么返回空字符串
package S12ChangeParameter;
public class Demo91Var03Practice02 {
// 需求二:n个字符串进行拼接,每一个字符串之间使用某字符进行分割,如果没有传入字符串,那么则返回空字符串
public static void main(String[] args) {
String result = concat(",","万事胜意","一切都会好的","我一直相信");
System.out.println(result);
}
public static String concat(String regex,String...s){
String str = "";
for (int i = 0; i < s.length; i++) {
if(i==s.length-1){
str+=s[i];
}else{
str+=s[i]+regex;
}
}
return str;
}
}