Day11/Day12——static关键字、枚举类、String_API

Day11

static关键字

由static关键字修饰的变量即为静态变量

成员变量分两种:

  1. 实例变量:没有static修饰,属于对象,存储于堆中,有几个对象就有几份,由实例化的对象访问

  2. 静态变量:static修饰,属于类,存储在方法区中,只有一份,由类名访问

    对象所共享的数据使用static修饰

class Aoo{
    int a;//实例变量
    static int b;//静态变量
}

示例:

public class StaticVar {
    int a;
    static int b;
    StaticVar(){
        a++;
        b++;
    }
    void show(){
        System.out.println("a = " + a + " b = " + b);
    }
}

public class StaticDemo {
    public static void main(String[] args) {
        StaticVar staticVar = new StaticVar();
        staticVar.show();
        StaticVar staticVar1 = new StaticVar();
        staticVar1.show();
        StaticVar staticVar2 = new StaticVar();
        staticVar2.show();
    }
}

输出结果:

a = 1 b = 1
a = 1 b = 2
a = 1 b = 3

分析:

静态变量加载内存图

静态代码块

  • 类加载到内存的时候就会执行静态代码块,一个类只加载一次,所以静态代码块只执行一次
  • 静态代码块的执行顺序:
    静态代码块 > 静态变量 > 构造代码块 > 构造方法

使用场景:初始化/加载静态资源

静态方法

访问实例变量和实例方法需要对象调用,this可以充当中间对象;

静态变量不需要对象调用,直接使用类名调用即可;

静态方法中没有隐式this,即没有中间对象,所以无法调用实例变量和实例方法,但是可以直接访问静态变量

实例方法中访问静态变量可以直接访问实例变量和静态变量,因为有隐式this作为对象调用实例

  • static修饰的方法即为静态方法
  • 属于类,存储在方法区,只有一份
  • 常通过类名访问
public class StaticMethod {
    int a; //实例变量,实例对象访问
    static  int b; //静态变量,类名访问
    public static void main(String[] args) {
        StaticMethod sm = new StaticMethod();
        sm.show();
    }
    void show(){ //实例方法,有隐式this
        System.out.println(this.a);
        System.out.println(StaticMethod.b);
    }
    static void test(){ //静态方法,无隐式this
        //System.out.println(this.a);//错误,静态方法中不能使用this
        //System.out.println(a); //错误,静态方法中没有this,所以无法不能使用实例变量
        System.out.println(b); //静态方法中可以直接调用静态变量
        //show(); //错误,静态方法中不能使用实例方法
    }
}

static final常量

  1. 必须声明的同时初始化,不嫩先声明再初始化
  2. 常通过类名来访问,不可改变
  3. 常量名全部大写
  4. 编译器编译时,会将常量直接替换为具体的数,效率高
  5. 当在程序中永远不变的数据可以使用static常量

枚举

  1. 是一种引用类型
  2. 枚举类型的对象数目是固定的,常用于定义一组常量,季节/星期/订单状态……
  3. 枚举的构造方法默认为私有的
  4. 枚举第一行罗列枚举对象名称

枚举的使用

枚举的定义

public enum Seasons {
    //编译后自动生成,底层自动实现
    //  public static final Seasons SPRING = new Seasons();
    //  public static final Seasons SUMMER = new Seasons();
    //  public static final Seasons AUTUMN = new Seasons();
    //  public static final Seasons WINTER = new Seasons();
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER;

    //编译后自动生成
    //  private Seasons() {}
}

常用api

season.name()

Seasons.values()

public class EnumTest {
    public static void main(String[] args) {
        Seasons season = Seasons.SPRING;//直接使用枚举类类名获取枚举对象
        System.out.println(season.name());//获取枚举对象的值
        Seasons[] seasons = Seasons.values();//获取枚举所有对象的值
        Arrays.stream(seasons).forEach(System.out::println);
        
        switch (season){ //switch常与枚举搭配
            case SPRING:
                System.out.println("春天");
                break;
            case AUTUMN:
                System.out.println("秋天");
                break;
            case SUMMER:
                System.out.println("夏天");
                break;
            case WINTER:
                System.out.println("冬天");
                break;
        }
    }
}

Day12

String类

String特点

  • String是不可变对象
  • java.lang.String使用了final修饰,不能被继承
  • 字符串底层封装了字符数组及针对字符数组的操作算法
  • 字符串一段创建,对象内容不可改变,连接字符串会创建新对象
  • Java字符串在内存中采用Unicode编码方式,任何一个字符对应两个字节的定长编码

String常量池

公共对象,不能修改,只有直接量赋值才会存入字符串常量池中

Java内存空间

java内存空间_String类

  • Java为了提高性能,直接量字符串创建后会缓存在字符串常量池中
  • 对于重复出现的字符串直接量,JVM会首先在常量池中查找,若存在即返回该对象来重用,不会重新生成
public static void main(String[] args) {
    String s1 = "123abc";//字符串常量池中首次创建对象
    String s2 = "123abc";//重用对象
    System.out.println(s1 == s2);//true
    String s3 =  "123abc";//重用对象
    System.out.println(s1 == s3);//true
    
    //使用new会强制创建新对象,Java不推荐使用new创建字符串
    String s4 = new String("123abc");
    System.out.println(s1 == s4);//false
    
    //字符串为不可变
    s1 = s1 + "!"; //拼接内容会创建新对象,不会在原对象(常量池中对象)上修改
    System.out.println(s1);//123abc!
    System.out.println(s2);//123abc
    System.out.println(s3);//123abc
}

编译器预计算特性

  1. 当运算符两侧均为直接量时,编译器会自动将运算结果直接写入字节码,而非创建新对象
  2. 使用直接量拼接对于某些场景会增加代码可读性
String s5 = "123abc";
String s6 = "123" + "abc";//s6重用字符串常量池对象
System.out.println(s5 == s6);//true
String s7 = "123";
String s8 = s7 + "abc";//JVM不会跨行识别,有一侧为变量,所以不会触发预编译
System.out.println("s8 == s6" + (s8 == s6));//false

常用方法

内存编码及长度

  • String在内存中采用Unicode编码,每个字符占两个字节
  • 任何一个字符(中文/英文/空格……)都选一个字符长度
  • ***length()***方法用于获取字符长度(空格也计入其中)
String str = "Hello World!";
int length = str.length();
System.out.println("字符串的长度是:" + length);//12

检索字符位置

  • ***IndexOf(String str)***方法用于实现在字符串中检索另一个字符串首次出现的位置
  • 检索成功则返回首次出现位置的坐标,检索失败则返回-1
String str = "think in java";
int index = str.indexOf("in");
System.out.println(index); // 输出 2

int index02 = str.indexOf("IN");
System.out.println(index02);// 输出 -1,因为字母"IN"大写
  • String提供了几个重载的IndexOf()方法:

    1. IndexOf(String str, int fromIndex)

      两个参数的含义

      1. 目标字符串
      2. 开始检索的位置坐标
      String str = "think in java";
      int index03 = str.indexOf("in", 3);
      System.out.println(index03);// 输出 6,从索引3开始搜索"in"
      
    2. lastIndexOf(String str)

      输出目标字符串最后一次出现的位置坐标

      String str = "think in java";
      int index04 = str.lastIndexOf("in");
      System.out.println(index04);// 输出 6,输出最后一次出现的索引位置
      

获取(截取)字串

***subString()***方法用于截取指定范围内的字符串子串

subString()的两种重载方法

  • subString(int start):截取从start开始到末尾的字符串
  • subString(int start, int end):截取从指定位置start开始到指定结束位置end的字符串,含左不含右
String str ="www.peng.com";
//截取从指定位置开始到最后的字符串
System.out.println("str.substring(4) = " + str.substring(4));
//截取从指定位置开始到指定结束位置end的字符串,含左不含右
System.out.println("str.substring(4,8) = " + str.substring(4, 8));

案例——获取网址中的域名

需求:在所提供的网址中提取域名,例如"http://www.tedu.com.cn"中提取“tedu”

实现:

private static String getHostName(String line) {
    int startIndex = line.indexOf(".")+1;//获取第一个点后的第一个字符的下标
    int endIndex = line.indexOf(".", startIndex);//获取第一个点下标的下一个点的下标
    if (startIndex > 0 && endIndex > 0) {
        return line.substring(startIndex+1,endIndex);
    }
    return null;
}

去除两侧空白

trim()方法用去去除字符串两侧的空白(空字符串)

注:只去除两侧,中间空白不去

String str = "  Hello World  ";
System.out.println("原始字符串:" + str);
// 去除字符串两端的空格
System.out.println(str.trim());

定位字符位置

charAt(char ch)方法用于定位指定字符在字符串中的位置

String str = "abcdefg";
for (int i = 0; i < str.length(); i++) {
    System.out.print(str.charAt(i)+" ");
}

检测字符串的开始与结尾

区分大小写,返回true或false

可以用于检验网址格式是否合法

  • boolean startWith(String str):用于检验目标字符串是不是以指定字符串开始
  • boolean endWith(String str):用于检验目标字符串是不是以指定字符串结尾
String str = "hello world";
boolean startCheck = str.startsWith("he");
boolean endCheck = str.endsWith("d");
System.out.println(startCheck); //true
System.out.println(endCheck); //true

改变字符大小写

只转变英文,不改变其他字符

可以用于验证码验证

  • toUpperCase():将字符串中的英文转换为全大写
  • toLowerCase():将字符串中的英文转换为全小写
  • equalsIgnoreCase():忽略大小写进行字符串比较
//验证码校验
String code = "a9Db5EcF";
System.out.println("请输入验证码:" + code);
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
if(input.toUpperCase().equals(code.toUpperCase())){
    System.out.println("验证码正确");
}else{
    System.out.println("验证码错误");
}
//思路二
if (input.equalsIgnoreCase(code)){
    System.out.println("验证码正确");
}

valueOf()

该方法为静态方法,使用String类名调用即可

  • String类提供了若干的静态的重载方法valueOf
  • valueOf()用于将其他类型转换为字符串类型
int a = 123;
String s = String.valueOf(s);
  • 转字符串的思路二
int a = 123;
String s = a + "";
  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值