Il existe 8 types de données de base en Java, quatre types entiers (octet, court, int, long), deux décimaux. types (float, double), un type de caractère (char) et un type booléen (boolean)
类型 | 字节 | 取值范围 |
---|---|---|
byte | 1 | -2^7 ~ 2^7 - 1 |
short | 2 | -2^15 ~ 2^15 - 1 |
int | 4 | -2^31 ~ 2^31 - 1 |
long | 8 | -2^63 ~ 2^63 - 1 |
(Un octet représente un binaire de 8 bits) float occupe 32 bits, double occupe 64 bits, char occupe 16 bits et boolean occupe 1 bit
Parce que Java est orienté objet Il s'agit d'un langage, donc ces huit types de données de base ont des classes d'empaquetage correspondantes : Byte, Short, Integer, Long, Float, Double, Character et Boolean. L'affectation entre ces huit types de base et leurs types d'emballage correspondants est complétée par l'encaissage et le déballage automatiques.
Integer a = 1; // 基本数据类型int自动装箱为Integer包装类(实际上在编译时会调用Integer .valueOf方法来装箱)int b = a; // 自动拆箱(实际上会在编译调用intValue)
Alors quelle est la différence entre new Integer(123)
et Integer.valueOf(123)
?
new Integer(123)
crée un objet à chaque fois et Integer.valueOf(123)
utilise des objets de cache, donc lorsque Integer.valueOf(123)
est utilisé plusieurs fois, seule une référence au même objet est obtenue.
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
Le compilateur appellera la méthode valueOf()
pendant le processus de boxe automatique, donc plusieurs instances Integer créées à l'aide de la boxe automatique et avec la même valeur référenceront le même objet.
Integer m = 123;Integer n = 123; System.out.println(m == n); // true
En examinant le code source de la classe Integer, il s'avère que lors de l'utilisation de valueOf()
, déterminez d'abord si la valeur est dans le pool de cache, et si c'est le cas, renvoyez directement le contenu du pool de cache.
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
Mais en regardant le code ci-dessous
Integer i1 = 128; Integer i2 = 128; System.out.println(i1 == i2); //false
nous constatons que false est renvoyé parce que dans Integer, la plage du pool de cache est : -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() {} }
En plus des huit types de données de base ci-dessus, la classe String est également le type le plus couramment utilisé dans l'écriture de programmes.
La classe String est déclarée finale, elle ne peut donc pas être héritée. Il utilise un tableau de caractères en interne pour stocker les données, et le tableau est déclaré comme final, ce qui signifie qu'une fois le tableau de valeurs initialisé, il ne peut pas référencer d'autres tableaux et il n'y a pas de méthode interne de String pour modifier le tableau de valeurs, donc String peut être garanti comme étant immuable.
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[];
String.intern()
L'utilisation de String.intern() peut garantir que les variables de chaîne avec le même contenu font référence au même objet mémoire.
Dans l'exemple suivant, s1 et s2 utilisent new String() pour créer deux nouveaux objets, et s3 obtient une référence d'objet via la méthode s1.intern(). Cette méthode convertit d'abord l'objet référencé par s1 Put. dans le pool de chaînes (pool de constantes de chaînes), puis renvoyez cette référence d'objet. Par conséquent, s3 et s1 font référence au même objet pool de constantes de chaîne.
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
Si vous utilisez "bbb" pour créer une instance de chaîne à l'aide de guillemets doubles, l'objet nouvellement créé sera automatiquement placé dans le pool de chaînes.
String s4 = "bbb";String s5 = "bbb"; System.out.println(s4 == s5); // true
Avant Java 7, le pool de constantes de chaîne était placé dans le pool de constantes d'exécution, qui appartenait à la génération permanente. Dans Java 7, le pool de constantes de chaîne est placé sur le tas. En effet, la génération permanente dispose d'un espace limité, ce qui peut provoquer des erreurs OutOfMemoryError dans les scénarios où les chaînes sont largement utilisées.
Alors sachant que String est immuable, quels sont les avantages de cette conception ?
1. La nécessité d'un pool de chaînes
Le pool de constantes de chaînes (pool interne String) est une zone de stockage spéciale dans la mémoire tas Java lors de la création d'un objet String. heure. Si cette valeur de chaîne existe déjà dans le pool de constantes, un nouvel objet ne sera pas créé, mais l'objet existant sera référencé.
2. Autoriser les objets String à mettre en cache HashCode
Le code de hachage des objets String en Java est fréquemment utilisé, par exemple dans des conteneurs tels que hashMap .
L'immuabilité des chaînes garantit le caractère unique du code de hachage, afin qu'il puisse être mis en cache en toute confiance. Il s'agit également d'une méthode d'optimisation des performances, ce qui signifie que vous n'avez pas besoin de calculer un nouveau code de hachage à chaque fois
3 Sécurité
La chaîne est utilisée par de nombreuses personnes. Les classes Java (bibliothèque) sont utilisées comme paramètres, tels que l'URL de l'adresse de connexion réseau, le chemin du fichier et les paramètres de chaîne requis par le mécanisme de réflexion, etc. Si la chaîne n'est pas corrigée, cela entraînera divers risques de sécurité.
boolean connect(string s){ if (!isSecure(s)) { throw new SecurityException(); } // 如果在其他地方可以修改String,那么此处就会引起各种预料不到的问题/错误 causeProblem(s); }
4. Sécurité des threads
L'immuabilité des chaînes est intrinsèquement thread-safe et peut être utilisée en toute sécurité dans plusieurs threads.
Cet article contient une introduction détaillée.
La chaîne est immuable, alors existe-t-il une chaîne mutable ?
fournit StringBuffer et StringBuilder en Java, qui sont variables. Dans String, un tableau de caractères final est défini, il est donc immuable. Cependant, comme StringBuffer et StringBuilder héritent de AbstractStringBuilder, il peut être vu dans le code source qu'il s'agit de tableaux de caractères variables.
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;
D'après le code source, on peut également savoir que StringBuffer est thread-safe, et ses méthodes sont toutes modifiées par synchronized
.
Articles connexes :
Types de données des connaissances de base de JavaScript_Connaissances de base
Types de données et flux de base en Java
Vidéos associées :
Aperçu et classification des types de données - Tutoriel vidéo JAVA pour débutant
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!