关于java String中intern的深入讲解


本文主要研究一下java String的intern

String.intern()

java.base/java/lang/String.java

public final class String
 implements java.io.Serializable, Comparable<String>, CharSequence,
    Constable, ConstantDesc {

 //......

 /**
  * Returns a canonical representation for the string object.
  * <p>
  * A pool of strings, initially empty, is maintained privately by the
  * class {@code String}.
  * <p>
  * When the intern method is invoked, if the pool already contains a
  * string equal to this {@code String} object as determined by
  * the {@link #equals(Object)} method, then the string from the pool is
  * returned. Otherwise, this {@code String} object is added to the
  * pool and a reference to this {@code String} object is returned.
  * <p>
  * It follows that for any two strings {@code s} and {@code t},
  * {@code s.intern() == t.intern()} is {@code true}
  * if and only if {@code s.equals(t)} is {@code true}.
  * <p>
  * All literal strings and string-valued constant expressions are
  * interned. String literals are defined in section 3.10.5 of the
  * <cite>The Java™ Language Specification</cite>.
  *
  * @return a string that has the same contents as this string, but is
  *   guaranteed to be from a pool of unique strings.
  * @jls 3.10.5 String Literals
  */
 public native String intern();

 //......   

}    
  • 当调用intern方法时,如果常量池已经包含一个equals此String对象的字符串,则返回池中的字符串
  • 当调用intern方法时,如果常量池没有一个equals此String对象的字符串,将此String对象添加到池中,并返回此String对象的引用(即intern方法返回指向heap中的此String对象引用)
  • 所有literal strings及string-valued constant expressions都是interned的

实例

基于jdk12

StringExistInPoolBeforeIntern

public class StringExistInPoolBeforeIntern {

 public static void main(String[] args){
  String stringObject = new String("tomcat");
  //NOTE 在intern之前,string table已经有了tomcat,因而intern返回tomcat,不会指向stringObject
  stringObject.intern();
  String stringLiteral = "tomcat";
  System.out.println(stringObject == stringLiteral); //false
 }
}
  • tomcat这个literal string是interned过的,常量池没有tomcat,因而添加到常量池,常量池有个tomcat;另外由于stringObject是new的,所以heap中也有一个tomcat,而此时它指向heap中的tomcat
  • stringObject.intern()返回的是heap中常量池的tomcat;stringLiteral是tomcat这个literal string,由于常量池已经有该值,因而stringLiteral指向的是heap中常量池的tomcat
  • 此时stringObject指向的是heap中的tomcat,而stringLiteral是heap中常量池的tomcat,因而二者不等,返回false

StringNotExistInPoolBeforeIntern

public class StringNotExistInPoolBeforeIntern {

 public static void main(String[] args){
  String stringObject = new String("tom") + new String("cat");
  //NOTE 在intern之前,string table没有tomcat,因而intern指向stringObject
  stringObject.intern();
  String stringLiteral = "tomcat";
  System.out.println(stringObject == stringLiteral); //true
 }
}
  • tom及cat这两个literal string是interned过的,常量池没有tom及cat,因而添加到常量池,常量池有tom、cat;另外由于stringObject是new出来的,是tom及cat二者concat,因而heap中有一个tomcat
  • stringObject的intern方法执行的时候,由于常量池中没有tomcat,因而添加到常量池,intern()返回的是指向heap中的tomcat的引用;stringLiteral是tomcat这个literal string,由于stringObject.intern()已经将tomcat添加到常量池了并指向heap中的tomcat的引用,所以stringLiteral返回的是指向heap中的tomcat的引用
  • 由于stringLiteral返回的是指向heap中的tomcat的引用,其实就是stringObject,因而二者相等,返回true

javap

基于jdk12

StringExistInPoolBeforeIntern

javac src/main/java/com/example/javac/StringExistInPoolBeforeIntern.java
javap -v src/main/java/com/example/javac/StringExistInPoolBeforeIntern.class

 Last modified 2019年4月6日; size 683 bytes
 MD5 checksum 207635ffd7560f1df24b98607e2ca7db
 Compiled from "StringExistInPoolBeforeIntern.java"
public class com.example.javac.StringExistInPoolBeforeIntern
 minor version: 0
 major version: 56
 flags: (0x0021) ACC_PUBLIC, ACC_SUPER
 this_class: #8       // com/example/javac/StringExistInPoolBeforeIntern
 super_class: #9       // java/lang/Object
 interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
 #1 = Methodref   #9.#21   // java/lang/Object."<init>":()V
 #2 = Class    #22   // java/lang/String
 #3 = String    #23   // tomcat
 #4 = Methodref   #2.#24   // java/lang/String."<init>":(Ljava/lang/String;)V
 #5 = Methodref   #2.#25   // java/lang/String.intern:()Ljava/lang/String;
 #6 = Fieldref   #26.#27  // java/lang/System.out:Ljava/io/PrintStream;
 #7 = Methodref   #18.#28  // java/io/PrintStream.println:(Z)V
 #8 = Class    #29   // com/example/javac/StringExistInPoolBeforeIntern
 #9 = Class    #30   // java/lang/Object
 #10 = Utf8    <init>
 #11 = Utf8    ()V
 #12 = Utf8    Code
 #13 = Utf8    LineNumberTable
 #14 = Utf8    main
 #15 = Utf8    ([Ljava/lang/String;)V
 #16 = Utf8    StackMapTable
 #17 = Class    #31   // "[Ljava/lang/String;"
 #18 = Class    #32   // java/io/PrintStream
 #19 = Utf8    SourceFile
 #20 = Utf8    StringExistInPoolBeforeIntern.java
 #21 = NameAndType  #10:#11  // "<init>":()V
 #22 = Utf8    java/lang/String
 #23 = Utf8    tomcat
 #24 = NameAndType  #10:#33  // "<init>":(Ljava/lang/String;)V
 #25 = NameAndType  #34:#35  // intern:()Ljava/lang/String;
 #26 = Class    #36   // java/lang/System
 #27 = NameAndType  #37:#38  // out:Ljava/io/PrintStream;
 #28 = NameAndType  #39:#40  // println:(Z)V
 #29 = Utf8    com/example/javac/StringExistInPoolBeforeIntern
 #30 = Utf8    java/lang/Object
 #31 = Utf8    [Ljava/lang/String;
 #32 = Utf8    java/io/PrintStream
 #33 = Utf8    (Ljava/lang/String;)V
 #34 = Utf8    intern
 #35 = Utf8    ()Ljava/lang/String;
 #36 = Utf8    java/lang/System
 #37 = Utf8    out
 #38 = Utf8    Ljava/io/PrintStream;
 #39 = Utf8    println
 #40 = Utf8    (Z)V
{
 public com.example.javac.StringExistInPoolBeforeIntern();
 descriptor: ()V
 flags: (0x0001) ACC_PUBLIC
 Code:
  stack=1, locals=1, args_size=1
   0: aload_0
   1: invokespecial #1     // Method java/lang/Object."<init>":()V
   4: return
  LineNumberTable:
  line 8: 0

 public static void main(java.lang.String[]);
 descriptor: ([Ljava/lang/String;)V
 flags: (0x0009) ACC_PUBLIC, ACC_STATIC
 Code:
  stack=3, locals=3, args_size=1
   0: new   #2     // class java/lang/String
   3: dup
   4: ldc   #3     // String tomcat
   6: invokespecial #4     // Method java/lang/String."<init>":(Ljava/lang/String;)V
   9: astore_1
  10: aload_1
  11: invokevirtual #5     // Method java/lang/String.intern:()Ljava/lang/String;
  14: pop
  15: ldc   #3     // String tomcat
  17: astore_2
  18: getstatic  #6     // Field java/lang/System.out:Ljava/io/PrintStream;
  21: aload_1
  22: aload_2
  23: if_acmpne  30
  26: iconst_1
  27: goto   31
  30: iconst_0
  31: invokevirtual #7     // Method java/io/PrintStream.println:(Z)V
  34: return
  LineNumberTable:
  line 11: 0
  line 13: 10
  line 14: 15
  line 15: 18
  line 16: 34
  StackMapTable: number_of_entries = 2
  frame_type = 255 /* full_frame */
   offset_delta = 30
   locals = [ class "[Ljava/lang/String;", class java/lang/String, class java/lang/String ]
   stack = [ class java/io/PrintStream ]
  frame_type = 255 /* full_frame */
   offset_delta = 0
   locals = [ class "[Ljava/lang/String;", class java/lang/String, class java/lang/String ]
   stack = [ class java/io/PrintStream, int ]
}
SourceFile: "StringExistInPoolBeforeIntern.java"
  • 可以看到常量池有个tomcat

StringNotExistInPoolBeforeIntern

javac src/main/java/com/example/javac/StringNotExistInPoolBeforeIntern.java
javap -v src/main/java/com/example/javac/StringNotExistInPoolBeforeIntern.class

 Last modified 2019年4月6日; size 1187 bytes
 MD5 checksum 6d173f303b61b8f5826e54bb6ed5157c
 Compiled from "StringNotExistInPoolBeforeIntern.java"
public class com.example.javac.StringNotExistInPoolBeforeIntern
 minor version: 0
 major version: 56
 flags: (0x0021) ACC_PUBLIC, ACC_SUPER
 this_class: #11       // com/example/javac/StringNotExistInPoolBeforeIntern
 super_class: #12      // java/lang/Object
 interfaces: 0, fields: 0, methods: 2, attributes: 3
Constant pool:
 #1 = Methodref   #12.#24  // java/lang/Object."<init>":()V
 #2 = Class    #25   // java/lang/String
 #3 = String    #26   // tom
 #4 = Methodref   #2.#27   // java/lang/String."<init>":(Ljava/lang/String;)V
 #5 = String    #28   // cat
 #6 = InvokeDynamic  #0:#32   // #0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 #7 = Methodref   #2.#33   // java/lang/String.intern:()Ljava/lang/String;
 #8 = String    #34   // tomcat
 #9 = Fieldref   #35.#36  // java/lang/System.out:Ljava/io/PrintStream;
 #10 = Methodref   #21.#37  // java/io/PrintStream.println:(Z)V
 #11 = Class    #38   // com/example/javac/StringNotExistInPoolBeforeIntern
 #12 = Class    #39   // java/lang/Object
 #13 = Utf8    <init>
 #14 = Utf8    ()V
 #15 = Utf8    Code
 #16 = Utf8    LineNumberTable
 #17 = Utf8    main
 #18 = Utf8    ([Ljava/lang/String;)V
 #19 = Utf8    StackMapTable
 #20 = Class    #40   // "[Ljava/lang/String;"
 #21 = Class    #41   // java/io/PrintStream
 #22 = Utf8    SourceFile
 #23 = Utf8    StringNotExistInPoolBeforeIntern.java
 #24 = NameAndType  #13:#14  // "<init>":()V
 #25 = Utf8    java/lang/String
 #26 = Utf8    tom
 #27 = NameAndType  #13:#42  // "<init>":(Ljava/lang/String;)V
 #28 = Utf8    cat
 #29 = Utf8    BootstrapMethods
 #30 = MethodHandle  6:#43   // REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
 #31 = String    #44   // \u0001\u0001
 #32 = NameAndType  #45:#46  // makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 #33 = NameAndType  #47:#48  // intern:()Ljava/lang/String;
 #34 = Utf8    tomcat
 #35 = Class    #49   // java/lang/System
 #36 = NameAndType  #50:#51  // out:Ljava/io/PrintStream;
 #37 = NameAndType  #52:#53  // println:(Z)V
 #38 = Utf8    com/example/javac/StringNotExistInPoolBeforeIntern
 #39 = Utf8    java/lang/Object
 #40 = Utf8    [Ljava/lang/String;
 #41 = Utf8    java/io/PrintStream
 #42 = Utf8    (Ljava/lang/String;)V
 #43 = Methodref   #54.#55  // java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
 #44 = Utf8    \u0001\u0001
 #45 = Utf8    makeConcatWithConstants
 #46 = Utf8    (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 #47 = Utf8    intern
 #48 = Utf8    ()Ljava/lang/String;
 #49 = Utf8    java/lang/System
 #50 = Utf8    out
 #51 = Utf8    Ljava/io/PrintStream;
 #52 = Utf8    println
 #53 = Utf8    (Z)V
 #54 = Class    #56   // java/lang/invoke/StringConcatFactory
 #55 = NameAndType  #45:#60  // makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
 #56 = Utf8    java/lang/invoke/StringConcatFactory
 #57 = Class    #62   // java/lang/invoke/MethodHandles$Lookup
 #58 = Utf8    Lookup
 #59 = Utf8    InnerClasses
 #60 = Utf8    (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
 #61 = Class    #63   // java/lang/invoke/MethodHandles
 #62 = Utf8    java/lang/invoke/MethodHandles$Lookup
 #63 = Utf8    java/lang/invoke/MethodHandles
{
 public com.example.javac.StringNotExistInPoolBeforeIntern();
 descriptor: ()V
 flags: (0x0001) ACC_PUBLIC
 Code:
  stack=1, locals=1, args_size=1
   0: aload_0
   1: invokespecial #1     // Method java/lang/Object."<init>":()V
   4: return
  LineNumberTable:
  line 8: 0

 public static void main(java.lang.String[]);
 descriptor: ([Ljava/lang/String;)V
 flags: (0x0009) ACC_PUBLIC, ACC_STATIC
 Code:
  stack=4, locals=3, args_size=1
   0: new   #2     // class java/lang/String
   3: dup
   4: ldc   #3     // String tom
   6: invokespecial #4     // Method java/lang/String."<init>":(Ljava/lang/String;)V
   9: new   #2     // class java/lang/String
  12: dup
  13: ldc   #5     // String cat
  15: invokespecial #4     // Method java/lang/String."<init>":(Ljava/lang/String;)V
  18: invokedynamic #6, 0    // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
  23: astore_1
  24: aload_1
  25: invokevirtual #7     // Method java/lang/String.intern:()Ljava/lang/String;
  28: pop
  29: ldc   #8     // String tomcat
  31: astore_2
  32: getstatic  #9     // Field java/lang/System.out:Ljava/io/PrintStream;
  35: aload_1
  36: aload_2
  37: if_acmpne  44
  40: iconst_1
  41: goto   45
  44: iconst_0
  45: invokevirtual #10     // Method java/io/PrintStream.println:(Z)V
  48: return
  LineNumberTable:
  line 11: 0
  line 13: 24
  line 14: 29
  line 15: 32
  line 16: 48
  StackMapTable: number_of_entries = 2
  frame_type = 255 /* full_frame */
   offset_delta = 44
   locals = [ class "[Ljava/lang/String;", class java/lang/String, class java/lang/String ]
   stack = [ class java/io/PrintStream ]
  frame_type = 255 /* full_frame */
   offset_delta = 0
   locals = [ class "[Ljava/lang/String;", class java/lang/String, class java/lang/String ]
   stack = [ class java/io/PrintStream, int ]
}
SourceFile: "StringNotExistInPoolBeforeIntern.java"
InnerClasses:
 public static final #58= #57 of #61; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
BootstrapMethods:
 0: #30 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
 Method arguments:
  #31 \u0001\u0001

可以看到常量池有tom、cat、tomcat

小结

当调用intern方法时,如果常量池已经包含一个equals此String对象的字符串,则返回池中的字符串
当调用intern方法时,如果常量池没有一个equals此String对象的字符串,将此String对象添加到池中,并返回此String对象的引用(即intern方法返回指向heap中的此String对象引用)

所有literal strings及string-valued constant expressions都是interned的

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • Java将Exception信息转为String字符串的方法

    一.前言 在java中,异常机制是非常有用的构成部分,异常信息对于查找错误来说是必不可少至关重要的信息,因此我们希望在发生错误的时候先看到捕捉到底异常信息.然而,通常的异常信息的输出使用e.printStackTrace(),这样异常信息会被输出到控制台中.但有的时候我们需要异常中的部分信息,需要他是一个可以处理的String类型. 二.解决方法 1.使用log4j 当我们使用log4j日志来记录运行信息时,可以直接使用下述方式: logger.error("异常信息:",e); 这样

  • 快速入门介绍Java中强大的String.format()

    前言 从 Java 5.0 开始,String 类新增了一个强大的字符串格式化方法 format().这个方法到现在用的人还是不多,实在是一种浪费.本文带你快速过一遍这个方法的功能,将来你要用到格式化文本的时候,可能就不需要再借用第三方类库或自己去实现了. 首先看一个简单例子: String formatted = String.format("%s今年%d岁.", "小李", 30); // "小李今年30岁." 不用我多解释,你也可以看出:

  • java判断String类型是否能转换为int的方法

    使用正则表达式,效率较高 public boolean canParseInt(String str){ if(str == null){ //验证是否为空 return false; } return str.matches("\\d+"); //使用正则表达式判断该字符串是否为数字,第一个\是转义符,\d+表示匹配1个或 //多个连续数字,"+"和"*"类似,"*"表示0个或多个 } 以上这篇java判断String类型是

  • 详解Java String字符串获取每一个字符及常用方法

    前言 对于字符串的操作,我们常用的就是trim()去除前后空格.subString()截取子字符串,其他的用的不多.下表中是字符串常用的方法.大家要记一记啊,特别是chartAt()方法比较重要的.因为一不小心就会被面试问到哦. 因为,本人偶尔会出去试试水,在一次随机面试过程中,就遇到面试官问的题:假设这里有个字符串String s = "aaabbbbccccdddd":问,如果去除掉重复的字母重新组成一个新的字符串.有几种解法? 一.循环字符串,解法 好吧,第一次碰到这种问题时,我

  • Java中StringUtils工具类进行String为空的判断解析

    判断某字符串是否为空,为空的标准是str==null或str.length()==0 1.下面是StringUtils判断是否为空的示例: StringUtils.isEmpty(null) = true StringUtils.isEmpty("") = true StringUtils.isEmpty(" ") = false //注意在 StringUtils 中空格作非空处理 StringUtils.isEmpty(" ") = fals

  • Java 8中字符串拼接新姿势StringJoiner详解

    在为什么阿里巴巴不建议在for循环中使用"+"进行字符串拼接一文中,我们介绍了几种Java中字符串拼接的方式,以及优缺点.其中还有一个重要的拼接方式我没有介绍,那就是Java 8中提供的StringJoiner ,本文就来介绍一下这个字符串拼接的新兵. 如果你想知道一共有多少种方法可以进行字符串拼接,教你一个简单的办法,在Intellij IDEA中,定义一个Java Bean,然后尝试使用快捷键自动生成一个toString方法,IDEA会提示多种toString生成策略可供选择. 1

  • java String的intern方法

    首先我们应该清楚的是JDK1.6和JDK1.7中String类的intern方法还是有差别的: JDK1.6中的intern:   调用intern方法的时候首先会去常量池中查看是否存在与当前String值相同的值,如果存在的话,则直接返回常量池中这个String值的引用:如果不存在的话,则会将原先堆中的该字符串拷贝一份到常量池中. JDK1.7中的intern:   调用intern方法的时候首先会去常量池中查看是否存在与当前String值相同的值,如果存在的话,则直接返回常量池中这个Stri

  • Java String的intern用法解析

    这篇文章主要介绍了Java String的intern用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在Java6中,intern方法返回的是对应字符串在永久态(方法区)中的地址:Java7以后,intern方法返回的是该字符串首次创建时候的堆内存的地址: 在java7中: package com.ecarx.daa.data.manager.utils; public class StringTest { public static

  • 关于java String中intern的深入讲解

    序 本文主要研究一下java String的intern String.intern() java.base/java/lang/String.java public final class String implements java.io.Serializable, Comparable<String>, CharSequence, Constable, ConstantDesc { //...... /** * Returns a canonical representation for

  • 详解Java String中intern方法的原理与使用

    目录 简介 常量池简介 intern方法简介(JDK7) 原理(JDK6与JDK7) 例程测试 例程分析 jdk1.6 jdk1.7 应用实例 简介 本文介绍Java的String的intern方法的原理. 常量池简介 在 JAVA 语言中有8种基本类型和一种比较特殊的类型String.这些类型为了使他们在运行过程中速度更快,更节省内存,都提供了一种常量池(在方法区)的概念.常量池就类似一个JAVA系统级别提供的缓存.8种基本类型的常量池都是系统协调的,String类型的常量池比较特殊. Str

  • String中intern方法的使用场景详解

    在讲intern方法前,我们先简单回顾下Java中常量池的分类. 常量池的分类# Java中常量池可以分为Class常量池.运行时常量池和字符串常量池. 1. Class文件常量池 在Class文件中除了有类的版本.字段.方法.接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用. 所谓字面量类似与我们平常说的常量,主要包括以下两种 文本字符串,例如String a = "aa".其中"aa"就是

  • Java String的intern方法使用场景示例

    在讲intern方法前,我们先简单回顾下Java中常量池的分类. 常量池的分类 Java中常量池可以分为Class常量池.运行时常量池和字符串常量池. 1. Class文件常量池 在Class文件中除了有类的版本.字段.方法.接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用. 所谓字面量类似与我们平常说的常量,主要包括以下两种 文本字符串,例如String a = "aa".其中"aa"就是字

  • Java String中移除空白字符的多种方式汇总

    前言 字符串,是Java中最常用的一个数据类型了.我们在日常开发时候会经常使用字符串做很多的操作.比如字符串的拼接.截断.替换等. 这一篇文章,我们介绍一个比较常见又容易被忽略的一个操作,那就是移除字符串中的空格. 其实,在Java中从字符串中删除空格有很多不同的方法,如trim,replaceAll等.但是,在Java 11添加了一些新的功能,如strip.stripLeading.stripTrailing等. 大多数时候,我们只是使用trim方法来删除多余的空格.但是好像很多人并没有去思考

  • JAVA开发中的一些规范讲解(阿里巴巴Java开发规范手册)

    一.编程规约 (一) 命名规约 1.   [强制]所有编程相关命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束.反例: _name / __name / $Object / name_ / name$ / Object$ 2.   [强制]所有编程相关的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式.说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义.注意,即使纯拼音命名方式也要避免采用. 反例: DaZhePromotion [打折] / getPingfen

  • Java String中的split方法使用总结

    目录 String中split方法使用 1.一般用法 2.需要转义的分隔符 3.多个符号作为分隔符 4.空值的存储 String.split()需要的转义字符 转义字符 String中split方法使用 String的split()方法用于按传入的字符或字符串对String进行拆分,返回拆分之后的数组. 1.一般用法 用一般的字符,例如@或,等符号做分隔符时: String address="上海@上海市@闵行区@吴中路"; String[] splitAddr=address.spl

  • Java自动化测试中多数据源的切换(实例讲解)

    在做自动化测试时,数据驱动是一个很重要的概念,当数据与脚本分离后,面对茫茫多的数据,管理数据又成了一个大问题,而数据源又可能面对多个,就跟在开发过程中,有时候要连接MYSQL,有时候又要连接SQL SERVER一样,如何做到快速切换?下面的示例中,我们将从一个数据源开始,一步步的演示下去: 一. 用外部文件做数据驱动的基本写法 1.1 我们在做数据驱动时,把数据存储在JAVA的属性文件中:data.properties username=test password=123456 1.2 解析pr

随机推荐