Java の基本の復習: 基本的なデータ型と String 型
1. 基本データ型
Java には、4 つの整数型 (byte、short、int、long)、2 つの 10 進数型 (float、double)、および 1 つの文字型 (char) の 8 つの基本データ型があります。 )、ブール型 (boolean)
type | byte | value range |
---|---|---|
byte | 1 | -2^7 ~ 2^7 - 1 |
短い | 2 | -2^15 ~ 2^15 - 1 |
int | 4 | -2^31 ~ 2^31 - 1 |
long | 8 | -2^63 ~ 2^ 63 - 1 |
(1 バイトは 8 ビットのバイナリを表します) float は 32 ビット、double は 64 ビット、char は 16 ビット、boolean は 1 ビットを占有します
Java はオブジェクト指向言語であるため、これら 8 つの基本データ型には対応するものがありますパッケージ化クラス: Byte、Short、Integer、Long、Float、Double、Character、Boolean。 これら 8 つの基本タイプとそれに対応するパッケージング タイプ間の割り当ては、自動ボックス化およびボックス化解除を使用して完了します。 Integer a = 1; // 基本数据类型int自动装箱为Integer包装类(实际上在编译时会调用Integer .valueOf方法来装箱)int b = a; // 自动拆箱(实际上会在编译调用intValue)
new Integer(123)
と Integer.valueOf(123)
の違いは何でしょうか?
new Integer(123)
は毎回オブジェクトを作成し、Integer.valueOf(123)
はキャッシュ オブジェクトを使用するため、Integer.valueOf は複数回使用されます ( 123)
の場合、同じオブジェクトへの参照のみが取得されます。 new Integer(123)
与 Integer.valueOf(123)
有什么区别?
new Integer(123)
每次都会创建一个对象,而 Integer.valueOf(123)
使用到了缓存对象,因此多次使用Integer.valueOf(123)
时,只会取得同一个对象的引用。
Integer a = new Integer(123);Integer b = new Integer(123); System.out.println(x == y); // falseInteger c = Integer.valueOf(123);Integer d = Integer.valueOf(123); System.out.println(z == k); // true
编译器会在自动装箱过程调用 valueOf()
方法,因此多个 Integer 实例使用自动装箱来创建并且值相同,那么就会引用相同的对象。
Integer m = 123;Integer n = 123; System.out.println(m == n); // true
根据查看Integer类的源码发现,使用valueOf()
时,先判断值是否在缓存池中,如果在的话就直接返回缓存池的内容。
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
但是看下面的代码
Integer i1 = 128; Integer i2 = 128; System.out.println(i1 == i2); //false
发现返回的是false,这是因为在Integer中,缓存池的范围为: -128 ~ 127
private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }
2.String类型
除了上面的八个基本数据类型,String类也是在写程序中最常用的一种类型。
String类被声明为final,所以它不可以被继承。其内部使用 char 数组存储数据,该数组被声明为 final,这意味着 value 数组初始化之后就不能再引用其它数组,并且 String 内部没有改变 value 数组的方法,因此可以保证 String 不可变。
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[];
String.intern()
使用 String.intern() 可以保证相同内容的字符串变量引用相同的内存对象。
下面示例中,s1 和 s2 采用 new String() 的方式新建了两个不同对象,而 s3 是通过 s1.intern() 方法取得一个对象引用,这个方法首先把 s1 引用的对象放到 String Pool(字符串常量池)中,然后返回这个对象引用。因此 s3 和 s1 引用的是同一个字符串常量池的对象。
String s1 = new String("aaa");String s2 = new String("aaa"); System.out.println(s1 == s2); // falseString s3 = s1.intern(); System.out.println(s1.intern() == s3); // true
如果是采用 “bbb” 这种使用双引号的形式创建字符串实例,会自动地将新建的对象放入 String Pool 中。
String s4 = "bbb";String s5 = "bbb"; System.out.println(s4 == s5); // true
在 Java 7 之前,字符串常量池被放在运行时常量池中,它属于永久代。而在 Java 7,字符串常量池被放在堆中。这是因为永久代的空间有限,在大量使用字符串的场景下会导致 OutOfMemoryError 错误。
那么知道String不可变性,那这样设计有什么好处呢?
1.字符串池的需要
字符串常量池(String intern pool) 是Java堆内存中一个特殊的存储区域, 当创建一个String对象时。假如此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已经存在的对象。
2.允许String对象缓存HashCode
Java中String对象的哈希码被频繁地使用, 比如在hashMap 等容器中。
字符串不变性保证了hash码的唯一性,因此可以放心地进行缓存。这也是一种性能优化手段,意味着不必每次都去计算新的哈希码
3.安全性
String被许多的Java类(库)用来当做参数,例如 网络连接地址URL,文件路径path,还有反射机制所需要的String参数等,假若String不是固定不变的,将会引起各种安全隐患。
boolean connect(string s){ if (!isSecure(s)) { throw new SecurityException(); } // 如果在其他地方可以修改String,那么此处就会引起各种预料不到的问题/错误 causeProblem(s); }
4.线程安全
String 不可变性天生具备线程安全,可以在多个线程中安全地使用。
这篇文章有详细的介绍。
String是不可变,那么有没有可变的字符串呢?
在Java中提供了StringBuffer 和 StringBuilder,是可变的。在String中,定义的是一个final字符数组,所以不可变,而StringBuffer和StringBuilder因为继承了AbstractStringBuilder,根据源码可看出是一个可变的字符数组。
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{
AbstractStringBuilder(int capacity) { value = new char[capacity]; } /** * The value is used for character storage. */ char[] value;
根据源码还可以知道,StringBuffer是线程安全的,其中的方法都被synchronized
rrreee
valueOf()
メソッドを呼び出すため、オートボックス化を使用して複数の Integer インスタンスが作成され、同じ値を持つ場合、それらは同じオブジェクトを参照します。 rrreee
Integer クラスのソース コードを見ると、valueOf()
を使用するときに、まず値がキャッシュ プールにあるかどうかを判断し、キャッシュ プールに存在する場合は直接その値を返すことがわかりました。キャッシュプールの内容。 rrreeeしかし、以下のコードを見るとrrreee
、これは整数のキャッシュプールの範囲が -128 ~ 127 であるためですrrreee
2.String 型
。上記に加えて、8 つの基本データ型の中で、String クラスはプログラムを作成する際に最もよく使用される型でもあります。 Stringクラスはfinal宣言されているため継承できません。データを格納するために内部的に char 配列を使用します。配列は Final として宣言されます。つまり、値配列が初期化された後は他の配列を参照できず、値配列を変更する String の内部メソッドがないため、String を使用できます。不変であることが保証されています。rrreee

synchronized
によって変更されていることもわかります。 🎜🎜関連記事: 🎜🎜🎜JavaScriptの基礎知識のデータ型_基礎知識🎜🎜🎜🎜Javaの基本的なデータ型とストリーム🎜🎜🎜関連動画: 🎜🎜データ型の概要と分類 - JAVA 初心者向けビデオチュートリアル
以上がJava の基本の復習: 基本的なデータ型と String 型の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











2025年のトップ4 JavaScriptフレームワーク:React、Angular、Vue、Svelte

カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?

Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?

Spring Boot Snakeyaml 2.0 CVE-2022-1471問題修正

キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?

高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?
