記事ディレクトリ
1文字列、長いソースコード分析
1.1文字列
- 不変性はStringクラスに由来し、クラス属性値[]はすべてfinalで変更されます。クラスは継承できず、そのメモリアドレスはプロパティの割り当て後に変更できません。
- 文字列が文字化けし、文字列がバイナリに変換される異なるシステムのデフォルトのエンコーディングのため、文字化けが発生します。
- 最初の文字の大文字、name.substring(0、1).toLowerCase()+ name.substring(1); name.substring(0、1).toUpperCase()+ name.substring(1)。
- 等価判定、メソッドはequals()およびequalsIgnoreCase()であり、2つの文字列が一致するかどうかを判断し、文字が1つずつ等しいかどうかを判断します
- 置換、削除、置換、replaceAll、replaceFirst。
- グアバツールの分割と結合、スプリッターとジョイナー。
1.2長い
- キャッシュの問題
キャッシュ-128〜127。この範囲内の値の場合、ここから値を取得します。内部静的クラスキャッシュデータ。
private static class LongCache {
private LongCache(){}
// 缓存,范围从 -128 到 127,+1 是因为有个 0
static final Long cache[] = new Long[-(-128) + 127 + 1];
// 容器初始化时,进行加载
static {
// 缓存 Long 值,注意这里是 i - 128 ,所以再拿的时候就需要 + 128
for(int i = 0; i < cache.length; i++)
cache[i] = new Long(i - 128);
}
}
1.3インタビュー
- 3.1 Longを使用するときは、parseLongメソッドを使用してvalueOfメソッドを多かれ少なかれ使用することをお勧めします。
回答:Long自体にはキャッシュメカニズムがあるため、-128から127の範囲のLongがキャッシュされます。valueOfメソッドは、キャッシュから値を取得します。キャッシュにヒットした場合、リソースのオーバーヘッドを削減します。parseLongメソッドにはこのメカニズムがありません。
2 Javaでよく使用されるキーワード
2.1静的
静的、クラス変数、メソッド、メソッドブロックを変更します。静的クラス変数は、同時に発生するセキュリティの問題に注意を払う必要があります。
初期化タイミング
public class Parent {
public static List<String> PARENT_LIST = new ArrayList() {{
System.out.println("parent 静态变量初始化");
}};
static {
System.out.println("parent 静态代码块初始化");
}
public Parent(){
System.out.println("parent 构造器初始化");
}
public void testStatic(){
System.out.println("parent 静态方法执行");
}
}
public class Son extends Parent {
public static List<String> LIST = new ArrayList() {{
System.out.println("son 静态变量初始化");
}};
static {
System.out.println("son 静态代码块初始化");
}
public Son() {
System.out.println("son 构造器初始化");
}
public void testSonStatic(){
System.out.println("son 静态方法执行");
}
public static void main(String[] args) {
System.out.println("main 执行");
new Son();
}
}
印刷結果:
親静的変数の初期化
親静的コードブロックの初期化
son静的変数の初期化
son静的コードブロックの初期化
main execute
parentコンストラクターの初期化
sonコンストラクターの初期化の
結論
- 親クラスの静的変数と静的コードブロックは、子クラスの前に初期化されます。
- 静的変数と静的コードブロックは、コンストラクタの前に初期化されます。
- 親クラスのコンストラクターは、子クラスの初期化よりも優先されます。
2.2最終
- finalによって変更されたクラスは継承できません。
- finalによって変更されたメソッドは、メソッドを上書きできないことを意味します。
- finalによって変更された変数は、宣言時に変数を初期化する必要があり、メモリアドレスは変更できないことを意味します。なお、メモリアドレスは変更できず、値は変更できませんリストやマップなどのオブジェクトは変更できます。
2.3ついにキャッチしよう
public class TryCatchFinally {
public static void main(String[] args) {
TryCatchFinally tryCatchFinally = new TryCatchFinally();
tryCatchFinally.test();
}
public void test(){
try {
System.out.println("log try");
if (true) {
throw new RuntimeException("try exception");
}
} catch (Exception e) {
System.out.println("log catch");
if (true) {
throw new RuntimeException("catch exception");
}
} finally {
System.out.println("log finally");
}
}
}
结果ログ
試行
ログキャッチ
ログ最終
的にスレッド「メイン」java.lang.RuntimeExceptionの例外:例外をキャッチ
- 最後に最初に実行し、次に例外をスローします。
2.4揮発性
揮発性、英語の説明:突然、予期せずに変化する可能性が高く、特に悪化することにより、揮発性を意味します。装飾された変数を共有するために使用されます。
**基礎となる原則:**複数のスレッドが複数のCPUで個別に実行される場合、スピードを上げるために、スレッドはメモリからではなくCPUキャッシュから共有変数を読み取らないため、スレッドの問題が発生します。 CPUキャッシュの存在による、変数Xの値は、スレッドBは、変数Xを知らない変更は、一貫性のない変数Xの値の問題にどのリードを変更されています。
解決策:変数Xをvolatileで変更します。スレッドAが変数Xの値を変更すると、メモリは他のCPUにそのCPUキャッシュの変数Xが無効であることを通知し、他のスレッドはメモリから変数Xを再度読み取り、データの一貫性を確保します。
2.5一時的
変更されたクラス変数は、クラスがシリアル化されるときにこの変数が無視されることを意味します。
2.6デフォルト
インターフェイスサブメソッドが無効であることを示すためにインターフェイスメソッドを変更するために使用されますが、インターフェイスにはデフォルトの実装が必要です。
public interface ParentInterface {
default void testMy() {
System.out.println("do something");
}
}
2.7インタビューの質問
- 静的変数がクラスに関連していないことを証明するにはどうすればよいですか?
- クラスを初期化する必要はありません。静的変数を直接使用できます。
- クラスのmainメソッドを記述します。クラスのコードが初期化されていなくても、静的変数は自動的に初期化されます。
- 静的変数は1回だけ初期化され、新しいクラスがいくつあっても、静的変数は1回だけ初期化されます。
3配列、コレクション、オブジェクトの共通メソッドのソースコード分析
3.1ツールの一般的な機能
- コンストラクタはプライベートであり、新しく作成する必要はありません。
- メソッドは通常、静的および最終的に変更されます。
3.2配列
配列は主に、ソート、検索、入力などの配列を処理するために使用されます。
3.2.1ソート
多くのパラメータタイプをサポートします。デモをご覧ください。
package demo.two;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.ImmutableList;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
@Slf4j
public class MyArraysDemoTest {
@Test
public void testSort() {
List<MySort> list = ImmutableList.of(
new MySort("100"),
new MySort("200"),
new MySort("600"),
new MySort("220"),
new MySort("150")
);
MySort[] mySorts = new MySort[list.size()];
list.toArray(mySorts);
log.info("before mySorts={}", JSON.toJSONString(mySorts));
Arrays.sort(mySorts, Comparator.comparing(MySort::getValue));
log.info("after mySorts={}", JSON.toJSONString(mySorts));
}
@Data
class MySort {
private String value;
public MySort(String value) {
this.value = value;
}
}
}
3.2.2バイナリサーチ
3.2.3コピー
copyOf()、copyOfRange()(部分コピー)。
3.3コレクション
コレクションで使用されるツール。
3.3.1最大値と最小値を見つける
Collections.max()およびmin()メソッド。
特別:<TはObject&Comparable <?Super T >>を拡張し、TはObjectクラスを継承してComparableインターフェースを実装する必要があることを意味します。
3.3.2複数のタイプのコレクション
スレッドセーフなコレクション(最初は同期)と不変のコレクション(最初は変更不可)があります。基礎となる実装を参照してください。
操作がロックされていることがわかります。
不変コレクションは、元のコレクションからの新しいコレクションで、読み取りのみが可能で、書き込みはできません。
3.4オブジェクト
主に、平等の判断と空の判断に使用されます。
3.4.1平等の判断
オブジェクトには、equalsとdeepEqualsの2つのメソッドがあり、前者は基本タイプとカスタムクラスを決定し、後者は配列を決定するために使用されます。
3.4.2判断
オブジェクトは、nullに関するさまざまな判断を提供します。IsNullおよびnonNullは、オブジェクトがnullかどうかのブール値を返します。requireNonNullメソッドはより厳密です。nullの場合、例外が直接スローされます。