1. 踩坑經歷 最近做了個需求,需要往公司微信公眾號推送一個模板消息,並且點擊該消息需要跳轉到公司小程式的某個頁面。 1.1 拿到模板id 既然是發送模板消息,第一步就需要登錄微信公眾號後臺新建模板消息,拿到模板id。 登錄地址:https://mp.weixin.qq.com 新建模板消息的方法如 ...
Object類
java.lang.Object
類是Java語言中的根類,每個類都使用 Object 作為超類, 所有的類都直接或間接繼承自 Object 類。所有對象(包括數組)都實現這個類的方法。
native 本地方法
在Object類的源碼中定義了native
修飾的方法,native
修飾的方法稱為本地方法。
特點
- 被native修飾的方法,非Java語言編寫,是由C++語言編寫。
- 本地方法在運行時期進入本地方法棧記憶體,本地方法棧是一塊獨立記憶體的區域。
- 本地方法的意義是和操作系統進行交互。
private static native void registerNatives();
static {
registerNatives();
}
當程式運行的時候,Object類會最先被載入到記憶體中。類進入記憶體後首先載入自己的靜態成員,static代碼塊中調用了本地方法registerNatives()
,和操作系統進行交互。
toString方法
方法聲明:public String toString()
:返回該對象的字元串表示。
Object類toString()方法源碼:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
源碼分析:
getClass().getName()
返回類的全限定名字。hashCode()
方法返回int值,可以暫時理解為對象的記憶體地址。Integer.toHexString()
將int類型的值轉成十六進位。- 因此調用對象的toString()方法將看到記憶體的地址值。
創建Person類,並調用方法toString()
public static void main(String[] args){
Person person = new Person();
String str = person.toString();
System.out.println(str);
System.out.println(person);
}
通過程式運行,得到結論,在輸出語句中列印對象,就是在調用對象的toString()方法。
重寫toString方法
由於toString方法返回的結果是記憶體地址,而在開發中,記憶體地址並沒有實際的應用價值,經常需要按照對象的屬性得到相應的字元串表現形式,因此也需要重寫它。
public class Person {
private String name;
private int age;
@Override
public String toString() {
return "Person"+name+":"+age;
}
// 省略構造器與Getter Setter
}
equals方法
方法聲明:public boolean equals(Object obj)
:指示其他某個對象是否與此對象“相等”。
Object類equals()方法源碼:
public boolean equals(Object obj) {
return (this == obj);
}
源碼分析:
- this是當前對象,哪個對象調用的equals方法就表示哪個對象。
- obj表述傳遞的參數,參數類型Object,可以傳遞任意類型對象。
- this==obj 比較兩個對象的記憶體地址是否相同
equals方法預設比較兩個對象的記憶體地址是否相同,相同則返回true。
重寫equals方法
實際應用中,比較記憶體地址是否相同並沒有意義,我們可以定義對象自己的比較方式,比較對象中成員變數的值是否相同。需要對方法進行重寫。
需求:重寫equals()方法,比較兩個對象中姓名和年齡是否相同,如果姓名和年齡都相同返回true,否則返回false。
public class Person {
private String name;
private int age;
public boolean equals(Object obj){
//判斷兩個對象地址弱相同,即為同一個對象
if(this == obj)
return true;
//obj對象為空,無需比較,返回false
if(obj == null)
return false;
//obj如果是Person類型對象,則強制轉換
if(obj instanceof Person){
Person person = (Person)obj;
//比較兩個對象的name屬性和age屬性,如果相等,返回true
return this.name.equals(person.name) && this.age == person.age;
}
return false;
}
}
hashCode方法
方法聲明 public native int hashCode();
返回一個哈希值
哈希值: 可以理解為一個唯一值 或 邏輯地址
調用hashCode, 比較兩對象的哈希, 相當於比較兩個對象的地址值
重寫hashCode, 比較兩對象的內容
若想確定內容是否真的相同 先比較兩對象的hashCode(因為比較數字較容易)
- 不同 說明兩對象內容一定不同
- 相同 不能說明兩對象一定相同 需要繼續比較 equals, 比較其內容
重寫hashCode方法
public int hashCode() {
// 成員變數是引用類型, 直接調用hashCode方法得到一個int值
// 成員變數是基本類型, 直接使用對應的值
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
String類
java.lang.String
類代表字元串。Java程式中所有的字元串文字(例如"abc"
)都可以被看作是實現此類的實例。
特點
1.字元串不變:字元串的值在創建後不能被更改。
String s1 = "abc";
s1 += "d";
System.out.println(s1); // "abcd"
// 記憶體中有"abc","abcd"兩個對象,s1從指向"abc",改變指向,指向了"abcd"。
2.因為String對象是不可變的,所以它們可以被共用。
String s1 = "abc";
String s2 = "abc";
// 記憶體中只有一個"abc"對象被創建,同時被s1和s2共用。
3."abc"
等效於 char[] data={ 'a' , 'b' , 'c' }
,但是底層原理是位元組數組( byte[] )
例如:
String str = "abc";
相當於:
char data[] = {'a', 'b', 'c'};
String str = new String(data);
// String底層是靠字元數組實現的。
構造方法
-
public String()
:初始化新創建的 String對象,以使其表示空字元序列。 -
public String(char[] value)
:通過當前參數中的字元數組來構造新的String。 -
public String(byte[] bytes)
:通過使用平臺的預設字元集解碼當前參數中的位元組數組來構造新的String。 -
直接賦值的方式創建字元串對象
構造舉例,代碼如下:
public class StringDemo01 {
public static void main(String[] args) {
//public String():創建一個空白字元串對象,不含有任何內容
String s1 = new String();
System.out.println("s1:" + s1);
//public String(char[] chs):根據字元數組的內容,來創建字元串對象
char[] chs = {'a', 'b', 'c'};
String s2 = new String(chs);
System.out.println("s2:" + s2);
//public String(byte[] bys):根據位元組數組的內容,來創建字元串對象
byte[] bys = {97, 98, 99};
String s3 = new String(bys);
System.out.println("s3:" + s3);
//String s = “abc”; 直接賦值的方式創建字元串對象,內容就是abc
String s4 = "abc";
System.out.println("s4:" + s4);
}
}
常用方法
獲取字元串的長度
public int length ()
: 返回此字元串的長度
字元串拼接
public String concat (String str)
:將指定的字元串連接到該字元串的末尾。
String s12 = "abc".concat("bcd");
System.out.println("concat拼接後: " + s12);
字元串 轉換為 字元數組
public char[] toCharArray()
char[] strToChar = s4.toCharArray();
for (int i = 0; i < strToChar.length; i++) {
System.out.print(strToChar[i] + " ");
}
System.out.println();
字元串 轉換為 位元組數組
public byte[] getBytes()
byte[] strToByte = s2.getBytes();
for (int i = 0; i < strToByte.length; i++) {
System.out.print(strToByte[i] + " ");
}
獲取指定索引位置的元素
public char charAt (int index)
:返回指定索引處的 char值。
// 根據索引找字元, 若索引不存在, 拋出StringIndexOutOfBoundsException(字元串索引越界異常)
String s = "I Love Java";
char c = s.charAt(0);
System.out.println(c);
for (int i = 0; i < s.length(); i++) {
System.out.print(s.charAt(i));
}
System.out.println();
獲取指定字元索引
public int indexOf (String str)
:返回指定子字元串第一次出現在該字元串內的索引。
int indexOf(String str, int fromIndex)
: 從指定索引位置開始查找
lastIndexOf(String str)
: 查找字元(串)最後一次出現的位置的索引
參數可以是char, int 或 String 類型
int index = s.indexOf('a');
System.out.println("字元a第一次出現的索引位置: " + index);
System.out.println("97對應的字元第一次出現的位置: " + s.indexOf(97) );
// 字元a第二次出現的索引位置
System.out.println("字元a第二次出現的索引位置: " + s.indexOf('a', index + 1) );
s1 = "abcaaaabcaab";
int abIndex = s1.indexOf("ab");
System.out.println("字元串ab第一次出現的索引位置: " + abIndex);
int abIndex2 = s1.indexOf("ab", abIndex + 1);
// int abIndex2 = s1.indexOf("ab", abIndex + "ab".length());
System.out.println("字元串ab第二次出現的索引位置: " + abIndex2);
System.out.println("字元串ab第三次出現的索引位置: " + s1.indexOf("ab", abIndex2 + 1));
String path = "d:\\work\\abc\\1.txt";
// 查詢字元'\'最後一次出現的位置
System.out.println(path.lastIndexOf('\\'));
字元串截取
substring(int startIndex)
: 從開始索引截取到末尾
substring(int startIndex, int endIndex)
: 截取字元串中 [start, end)的字元串
因為字元串不可改變, 所以返回一個新的字元串
// 截取Love
String subLove = s.substring(2, 6);
System.out.println(subLove);
// 截取文件名
int lastIndex = path.lastIndexOf('\\');
String fileName = path.substring(lastIndex + 1);
System.out.println(fileName);
去除字元串兩端空格
public String trim()
String s13 = " ab c ";
System.out.println("原字元串: " + s13);
System.out.println("去除兩端空格: " + s13.trim());
字元串替換
public String replace (CharSequence target, CharSequence replacement)
: 將與target匹配的字元串使用replacement字元串替換
public String replaceAll(String regex, String replacement)
: 將與regex(正則)匹配的字元串使用replacement字元串替換
區別: replaceAll支持正則表達式, 而replace不支持
String s14 = "張三-李四-王五-趙六";
String s15 = s14.replace("-", " ");
System.out.println("replace替換: " + s15);
s14 = "張三--------李四---王五--趙六";
String s16 = s14.replaceAll("-+", " ");
System.out.println("replaceAll替換: " + s16);
切割字元串
public String[] split(String regex)
:將此字元串按照給定的regex(正則)拆分為字元串數組
String[] strArr = s14.split("-+");
for (String s : strArr) {
System.out.print(s + " ");
}
System.out.println();
// 以'.'分割ip地址
String myIp = "192.168.1.1";
// '.'在正則中表示匹配任意字元, '\'為轉義符, java要拿到'\', 需要對'\'轉義, 即'\\'
strArr = myIp.split("\\.");
for (String s: strArr) {
System.out.print(s + " ");
}
System.out.println();