跳转到帖子

游客您好,欢迎来到黑客世界论坛!您可以在这里进行注册。

赤队小组-代号1949(原CHT攻防小组)在这个瞬息万变的网络时代,我们保持初心,创造最好的社区来共同交流网络技术。您可以在论坛获取黑客攻防技巧与知识,您也可以加入我们的Telegram交流群 共同实时探讨交流。论坛禁止各种广告,请注册用户查看我们的使用与隐私策略,谢谢您的配合。小组成员可以获取论坛隐藏内容!

TheHackerWorld官方

精选回复

发布于
 String Class - 字符串类型 - 上半部分讲解 - Java - 细节狂魔    300

前言

  字符串: 在C语言里面 是 没有字符串类型的! 但是,在 Java 和 C++ 里,有字符串类型【String】

什么是字符串?什么是字符?

  使用双引号,且双引号中包含任意数量的字符【“abcdef”,“a”】,就是字符串。 使用单引号,且单引号中,只包含一个字符【‘a’,‘强’】,就是字符。

注意问题:

  1. 在Java当中,没有所谓的字符串以 ‘’ 结尾。 2. String 类 ,不能继承。

创建字符串

  创建方法与创建数组,几乎一样。

第一种:直接赋值


第二种: 调用构造方法进行构造对象(就是去new‘一个)


第三种:

public class Test {
          
   
    public static void main(String[] args) {
          
   
        char[] chars = {
          
   a,b,c};
        String str3 = new String(chars);
        System.out.println(str3);

    }
}

了解字符串类型

  按住Ctrl,点击String,进入String

根据上图,我们发现对于字符串来说,有两个属性,一个是char 类型的 value数组(此时这个数组,只是一个变量【引用类型】,没有给这个数组,分配内存。也没有new)。一个是 哈希码。

这里先给大家打个底,后面,我会详细讲解.。 我们先来搞懂String的对象(通过创建字符串的第三种方法) String 常用的构造方法就是数组

注意事项

“hello” 这样的字符串字面值常量, 类型也是 String. String 也是引用类型. String str = “Hello”; 这样的代码内存布局如下 ^**

例题一

public class Test {
          
   
    public static void main(String[] args) {
          
   
        String str = "abcef";
        String str2 = str;
        System.out.println(str);
        System.out.println(str2);
    }
}

效果图

附图

例题2: 将例题1中的 str,重新赋值会不会影响 str2的输出结果?


在上面两个例题中,我们需要搞懂:字符串常量是不能被改变的

例如: String str = “abcd”; 通过引用 str 去将 字符串"abcd" 修改成 “gbcd”. 答案是做不到的,因为被双引号引起来的是字面值常量,常量是不能被修改的。 例题2中,str = “author”; 这句代码是将str重新指向一个新的对象(修改str的指向),而不是将原来的字符串对象修改成author。

下面,我们来更深层次的分析一下为什么字符串不能被修改

实例1

import java.util.Arrays;

public class Test {
          
   
    public static void func(String s,char[] array){
          
   
        s = "author";
        array[0] = p;
    }
    public static void main(String[] args) {
          
   
        String str = "abcd";
        char[] chars = {
          
   y,o,u};
        func(str,chars);
        System.out.println(str);
        System.out.println(Arrays.toString(chars));
    }
}

附图

结论:
不是说 转引用 就能改变实参的值。 你要看,到底这个引用干了什么!

实例2

public class Test {
          
   
    public static void main(String[] args) {
          
   
        String str1 = "hello";
        String str2 = new String("hello");
        System.out.println(str1 == str2);
    }
}

效果图

附图


实例3

import java.util.Arrays;

public class Test {
          
   
    public static void main(String[] args) {
          
   
        String str1 = "hello";
        String str2 = "hello";
        System.out.println(str1==str2);
    }
}

效果图

附图


实例4

public class Test {
          
   
    public static void main(String[] args) {
          
   
        String str1 = "hello";
        String str2 = "he"+"llo";// 注意:此时两个字符串都是常量,且在编译的时候就已经确定了是"hello"
        // 简单来说像这种 直接拿两个字符串常量来拼接的,在编译时,就默认是拼接好了的,或者说 默认就是一个完整的字符串常量
        System.out.println(str1 == str2);
    }
}

效果图

附图

找到 main 部分

实例5

public class Test {
          
   
    public static void main(String[] args) {
          
   
        String str1 = "hello";
        String str2 = "he";
        String str3 = str1+"llo";
        System.out.println(str1 == str3);
    }
}

效果图


实例6

public class Test {
          
   
    public static void main(String[] args) {
          
   
        String str1 = "11";
        String str2 = new String("1")+ new String("1");
        System.out.println(str1==str2);
    }
}

效果图(很明显答案是false,一个完整,一个拼接。两者肯定不同)

附图(底层分析)


实例7


实例7(特别版)

如果 我在程序中,在 str2后面加上一句代码 str2.intern(); 呢? intern() 的作用:将它的调用者,手动入池。
public class Test {
          
   
    public static void main(String[] args) {
          
   
        String str2 = new String("1")+ new String("1");
        str2.intern();
        String str1 = "11";
        System.out.println(str1==str2);
    }
}

效果图

附图


字符串比较

如果是引用类型变量之间的比较,且使用双等号来比较的话,比较的就是引用变量存储的地址。相信大家应该明白,上面的例题就是这样比较的。

equals

语法 调用者.equals(); 如果调用是引用类型的数据,就需要注意,调用者不能空引用/空指针。防止出现空指针异常错误

拓展

在Java中,new String类型数据的时候,是不会存在内存重叠的情况,在Java中,字符串是一个对象,而我们new String 对象时,是产生一个新的对象,如果产生的对象是一样的,那还叫新对象??


String 类型的数据不可变


数组的整体赋值 ,在Java中,只有一次机会,就是在定义数组的时候。

例子1


例子2


例子3


特殊引用


字符串拼接

;public class Test2 {
          
   
    public static void main(String[] args) {
          
   
        String str = "hello";
        str =str + " world";
        str+="!!!";
        System.out.println(str);
    }
}

附图


特殊:String 类型的数据,可以通过反射修改

还是上一个程序,如果我非要把字符串"abcde"的 a 改成 g 呢? 可以,前面我们也看到,String类型的数据,是数组的形式存储在对上,既然是数组,那么我们可以通过下标去修改它, 但是问题是 value 的权限是private 是 私有的 所以,即使我们拿到了对象,都拿不到value的 但是 反射 就可以走到,反射的功能异常强大。 反射 是什么? 举一个很形象的例子: 我们每次坐地铁,我们所带的行李箱,都需要进过安检,了解过的都知道,安检的机器,会发射一中光谱的曲线,通过反射,就能知道我们的行李箱中装了什么东西。从这里就体现出了 “反射” 的 概念 这里是类比一下, 通过"反射"。我们能看到类里面存储的一些属性,哪怕是私有的,又或者是上锁了。我都能看到, 也就是说:通过反射,我们能获取其中所有信息。 其实 反射就是最大bug,用得好,那叫一个nice,用的不好,那叫一个难受。

创建帐户或登录后发表意见

最近浏览 0

  • 没有会员查看此页面。