国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Maison Java javaDidacticiel Analyse du code source de la cha?ne Java

Analyse du code source de la cha?ne Java

Feb 27, 2017 pm 03:25 PM

Analyse du code source de la cha?ne Java

Qu'est-ce qu'un objet immuable??

Comme nous le savons tous, en Java, la classe String est immuable. Alors, que sont exactement les objets immuables ? Vous pouvez y penser de cette fa?on?: si un objet ne peut pas changer d'état après sa création, alors l'objet est immuable. L'état ne peut pas être modifié, ce qui signifie que les variables membres au sein de l'objet ne peuvent pas être modifiées, y compris les valeurs des types de données de base. Les variables des types référence ne peuvent pas pointer vers d'autres objets, et l'état des objets pointés par les types référence ne peut pas. être changé.

Distinguer les objets et les références d'objets

Pour les débutants en Java, il y a toujours des doutes sur le fait que String soit un objet immuable. Regardez le code suivant?:

String s = "ABCabc"; 
System.out.println("s = " + s); 
 
s = "123456"; 
System.out.println("s = " + s);

Le résultat imprimé est?:

s = ABCabc
s = 123456

Créez d'abord un objet String s, puis laissez la valeur de s être "ABCabc", puis laissez la valeur de s être "123456". Comme le montrent les résultats imprimés, la valeur de s a effectivement changé. Alors pourquoi dites-vous encore que les objets String sont immuables ? En fait, il y a ici un malentendu?: s est simplement une référence à un objet String, pas à l'objet lui-même. L'objet est une zone mémoire dans la mémoire. Plus il y a de variables membres, plus l'espace occupé par cette zone mémoire est grand. Une référence n'est qu'une donnée de 4 octets qui stocke l'adresse de l'objet vers lequel elle pointe. L'objet est accessible via cette adresse.

En d'autres termes, s est juste une référence, qui pointe vers un objet spécifique. Lorsque s="123456"; après l'exécution de ce code, un nouvel objet "123456" est créé et la référence s re. -pointe vers l'objet c?ur, et l'objet d'origine "ABCabc" existe toujours dans la mémoire et n'a pas changé. La structure de la mémoire est la suivante?:

Java String源碼分析

Une différence entre Java et C est qu'il est impossible d'exploiter directement l'objet lui-même en Java All. objets Ils sont tous pointés par une référence, et cette référence doit être utilisée pour accéder à l'objet lui-même, notamment obtenir la valeur des variables membres, modifier les variables membres de l'objet, appeler les méthodes de l'objet, etc. En C, il y a trois choses : les références, les objets et les pointeurs, qui peuvent tous trois accéder aux objets. En fait, les références en Java sont conceptuellement similaires aux pointeurs en C. Ce sont toutes deux les valeurs d'adresse des objets stockés en mémoire. Cependant, en Java, les références ont perdu une partie de leur flexibilité. Par exemple, les références en Java ne peuvent pas être utilisées. comme Ajouter et soustraire comme des pointeurs en C.

Pourquoi les objets String sont-ils immuables??

Pour comprendre l'immuabilité de String, jetez d'abord un ?il aux variables membres de la classe String. Dans JDK1.6, les variables membres de String incluent les éléments suivants?:

public final class String 
  implements java.io.Serializable, Comparable<String>, CharSequence 
{ 
  /** The value is used for character storage. */ 
  private final char value[]; 
 
  /** The offset is the first index of the storage that is used. */ 
  private final int offset; 
 
  /** The count is the number of characters in the String. */ 
  private final int count; 
 
  /** Cache the hash code for the string */ 
  private int hash; // Default to 0

Dans JDK1.7, la classe String a apporté quelques modifications, principalement It modifie le comportement de la méthode substring lors de son exécution, ce qui n'est pas lié au sujet de cet article. Il n'y a que deux variables membres principales de la classe String dans JDK1.7?:

public final class String 
  implements java.io.Serializable, Comparable<String>, CharSequence { 
  /** The value is used for character storage. */ 
  private final char value[]; 
 
  /** Cache the hash code for the string */ 
  private int hash; // Default to 0

Comme le montre le code ci-dessus, String en Java A la classe est en fait une encapsulation d’un tableau de caractères. Dans JDK6, value est un tableau encapsulé par String, offset est la position de départ de String dans le tableau de valeurs et count est le nombre de caractères occupés par String. Dans JDK7, il n'y a qu'une seule variable de valeur, c'est-à-dire que tous les caractères de la valeur appartiennent à l'objet String. Ce changement n’affecte pas la discussion de cet article. De plus, il existe une variable membre de hachage, qui est un cache de la valeur de hachage de l'objet String. Cette variable membre n'est pas non plus pertinente pour la discussion de cet article. En Java, les tableaux sont aussi des objets (veuillez vous référer à mon article précédent Caractéristiques des tableaux en Java). La valeur est donc simplement une référence qui pointe vers un véritable objet tableau. En fait, après avoir exécuté le code String s = "ABCabc";, la véritable disposition de la mémoire devrait ressembler à ceci?:


Java String源碼分析

Les trois variables value, offset et count sont toutes privées, et aucune méthode publique telle que setValue, setOffset et setCount n'est fournie pour modifier ces valeurs, donc String ne peut pas être modifié en dehors de la classe String. C'est-à-dire qu'une fois initialisé, il ne peut plus être modifié et ces trois membres ne sont pas accessibles en dehors de la classe String. De plus, les trois variables value, offset et count sont toutes définitives, ce qui signifie qu'au sein de la classe String, une fois ces trois valeurs initialisées, elles ne peuvent plus être modifiées. L'objet String peut donc être considéré comme immuable.

Ensuite, dans String, il existe évidemment des méthodes, et les appeler peut obtenir la valeur modifiée. Ces méthodes incluent substring, replace, replaceAll, toLowerCase, etc. Par exemple, le code suivant?:

String a = "ABCabc"; 
System.out.println("a = " + a); 
a = a.replace(&#39;A&#39;, &#39;a&#39;); 
System.out.println("a = " + a);

Le résultat imprimé est?:

a = ABCabc
a = aBCabc

那么a的值看似改變了,其實(shí)也是同樣的誤區(qū)。再次說(shuō)明, a只是一個(gè)引用, 不是真正的字符串對(duì)象,在調(diào)用a.replace('A', 'a')時(shí), 方法內(nèi)部創(chuàng)建了一個(gè)新的String對(duì)象,并把這個(gè)心的對(duì)象重新賦給了引用a。String中replace方法的源碼可以說(shuō)明問(wèn)題:

Java String源碼分析

讀者可以自己查看其他方法,都是在方法內(nèi)部重新創(chuàng)建新的String對(duì)象,并且返回這個(gè)新的對(duì)象,原來(lái)的對(duì)象是不會(huì)被改變的。這也是為什么像replace, substring,toLowerCase等方法都存在返回值的原因。也是為什么像下面這樣調(diào)用不會(huì)改變對(duì)象的值:

String ss = "123456"; 
 
System.out.println("ss = " + ss); 
 
ss.replace(&#39;1&#39;, &#39;0&#39;); 
 
System.out.println("ss = " + ss);

打印結(jié)果:

ss = 123456
ss = 123456

String對(duì)象真的不可變嗎?

從上文可知String的成員變量是private final 的,也就是初始化之后不可改變。那么在這幾個(gè)成員中, value比較特殊,因?yàn)樗且粋€(gè)引用變量,而不是真正的對(duì)象。value是final修飾的,也就是說(shuō)final不能再指向其他數(shù)組對(duì)象,那么我能改變value指向的數(shù)組嗎? 比如將數(shù)組中的某個(gè)位置上的字符變?yōu)橄聞澗€“_”。 至少在我們自己寫(xiě)的普通代碼中不能夠做到,因?yàn)槲覀兏静荒軌蛟L問(wèn)到這個(gè)value引用,更不能通過(guò)這個(gè)引用去修改數(shù)組。

那么用什么方式可以訪問(wèn)私有成員呢? 沒(méi)錯(cuò),用反射, 可以反射出String對(duì)象中的value屬性, 進(jìn)而改變通過(guò)獲得的value引用改變數(shù)組的結(jié)構(gòu)。下面是實(shí)例代碼:

public static void testReflection() throws Exception { 
   
  //創(chuàng)建字符串"Hello World", 并賦給引用s 
  String s = "Hello World";  
   
  System.out.println("s = " + s); //Hello World 
   
  //獲取String類(lèi)中的value字段 
  Field valueFieldOfString = String.class.getDeclaredField("value"); 
   
  //改變value屬性的訪問(wèn)權(quán)限 
  valueFieldOfString.setAccessible(true); 
   
  //獲取s對(duì)象上的value屬性的值 
  char[] value = (char[]) valueFieldOfString.get(s); 
   
  //改變value所引用的數(shù)組中的第5個(gè)字符 
  value[5] = &#39;_&#39;; 
   
  System.out.println("s = " + s); //Hello_World 
}

打印結(jié)果為:

s = Hello World
s = Hello_World

在這個(gè)過(guò)程中,s始終引用的同一個(gè)String對(duì)象,但是再反射前后,這個(gè)String對(duì)象發(fā)生了變化, 也就是說(shuō),通過(guò)反射是可以修改所謂的“不可變”對(duì)象的。但是一般我們不這么做。這個(gè)反射的實(shí)例還可以說(shuō)明一個(gè)問(wèn)題:如果一個(gè)對(duì)象,他組合的其他對(duì)象的狀態(tài)是可以改變的,那么這個(gè)對(duì)象很可能不是不可變對(duì)象。例如一個(gè)Car對(duì)象,它組合了一個(gè)Wheel對(duì)象,雖然這個(gè)Wheel對(duì)象聲明成了private final 的,但是這個(gè)Wheel對(duì)象內(nèi)部的狀態(tài)可以改變, 那么就不能很好的保證Car對(duì)象不可變。

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

更多Java String源碼分析相關(guān)文章請(qǐng)關(guān)注PHP中文網(wǎng)!


Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefa?on, veuillez contacter admin@php.cn

Outils d'IA chauds

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

échangez les visages dans n'importe quelle vidéo sans effort grace à notre outil d'échange de visage AI entièrement gratuit?!

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Différence entre le hashmap et le hashtable? Différence entre le hashmap et le hashtable? Jun 24, 2025 pm 09:41 PM

La différence entre le hashmap et le hashtable se reflète principalement dans la sécurité des threads, la prise en charge de la valeur nul et les performances. 1. En termes de sécurité des threads, le hashtable est en filetage et ses méthodes sont principalement des méthodes synchrones, tandis que HashMAP n'effectue pas de traitement de synchronisation, qui n'est pas un filetage; 2. En termes de support de valeur nulle, HashMap permet une clé nul et plusieurs valeurs nulles, tandis que le hashtable ne permet pas les clés ou les valeurs nulles, sinon une nulpointerexception sera lancée; 3. En termes de performances, le hashmap est plus efficace car il n'y a pas de mécanisme de synchronisation et le hashtable a une faible performance de verrouillage pour chaque opération. Il est recommandé d'utiliser à la place ConcurrentHashMap.

Quelles sont les méthodes statiques dans les interfaces? Quelles sont les méthodes statiques dans les interfaces? Jun 24, 2025 pm 10:57 PM

StaticMethodsinInterfaceswereintrocedInjava8TollowutilityfonctionwithIntheInterface self.beforejava8, telfunctionsrequuresepatehelperclasses, leadstodisorganizedCode.now, staticmethodsprovidethrekeyefits: 1) ils sont en train

Comment le compilateur JIT optimise-t-il le code? Comment le compilateur JIT optimise-t-il le code? Jun 24, 2025 pm 10:45 PM

Le compilateur JIT optimise le code à travers quatre méthodes: méthode en ligne, détection et compilation de points chauds, spéculation et dévigtualisation de type et élimination redondante. 1. La méthode en ligne réduit les frais généraux d'appel et inserte fréquemment appelées petites méthodes directement dans l'appel; 2. Détection de points chauds et exécution de code haute fréquence et optimiser de manière centralisée pour économiser des ressources; 3. Type Speculations collecte les informations de type d'exécution pour réaliser des appels de déviptualisation, améliorant l'efficacité; 4. Les opérations redondantes éliminent les calculs et les inspections inutiles en fonction de la suppression des données opérationnelles, améliorant les performances.

Qu'est-ce qu'un bloc d'initialisation d'instance? Qu'est-ce qu'un bloc d'initialisation d'instance? Jun 25, 2025 pm 12:21 PM

Les blocs d'initialisation d'instance sont utilisés dans Java pour exécuter la logique d'initialisation lors de la création d'objets, qui sont exécutés avant le constructeur. Il convient aux scénarios où plusieurs constructeurs partagent le code d'initialisation, l'initialisation du champ complexe ou les scénarios d'initialisation de classe anonyme. Contrairement aux blocs d'initialisation statiques, il est exécuté à chaque fois qu'il est instancié, tandis que les blocs d'initialisation statiques ne s'exécutent qu'une seule fois lorsque la classe est chargée.

Quel est le modèle d'usine? Quel est le modèle d'usine? Jun 24, 2025 pm 11:29 PM

Le mode d'usine est utilisé pour encapsuler la logique de création d'objets, ce qui rend le code plus flexible, facile à entretenir et à couplé de manière lache. La réponse principale est: en gérant de manière centralisée la logique de création d'objets, en cachant les détails de l'implémentation et en soutenant la création de plusieurs objets liés. La description spécifique est la suivante: Le mode d'usine remet la création d'objets à une classe ou une méthode d'usine spéciale pour le traitement, en évitant directement l'utilisation de newClass (); Il convient aux scénarios où plusieurs types d'objets connexes sont créés, la logique de création peut changer et les détails d'implémentation doivent être cachés; Par exemple, dans le processeur de paiement, Stripe, PayPal et d'autres instances sont créés par le biais d'usines; Son implémentation comprend l'objet renvoyé par la classe d'usine en fonction des paramètres d'entrée, et tous les objets réalisent une interface commune; Les variantes communes incluent des usines simples, des méthodes d'usine et des usines abstraites, qui conviennent à différentes complexités.

Quel est le mot-clé ?final? des variables? Quel est le mot-clé ?final? des variables? Jun 24, 2025 pm 07:29 PM

Injava, thefinalkeywordpreventsavariable'svaluefrombeingchangedafterAsssignment, mais cetsbehaviDiffersFortimitives et objectreferences.forprimitivevariables, finalMakeShevalueConstant, AsinfininTMax_peed = 100; whitereSsignmentCausAnesanerror.ForobjectRe

Pourquoi avons-nous besoin de cours d'emballage? Pourquoi avons-nous besoin de cours d'emballage? Jun 28, 2025 am 01:01 AM

Java utilise des classes de wrapper car les types de données de base ne peuvent pas participer directement aux opérations orientées objet, et les formulaires d'objets sont souvent nécessaires dans les besoins réels; 1. Les classes de collecte ne peuvent stocker que des objets, tels que les listes, l'utilisation de la boxe automatique pour stocker des valeurs numériques; 2. Les génériques ne prennent pas en charge les types de base et les classes d'emballage doivent être utilisées comme paramètres de type; 3. Les classes d'emballage peuvent représenter les valeurs nulles pour distinguer les données non définies ou manquantes; 4. Les cours d'emballage fournissent des méthodes pratiques telles que la conversion de cha?nes pour faciliter l'analyse et le traitement des données, donc dans les scénarios où ces caractéristiques sont nécessaires, les classes de packaging sont indispensables.

Qu'est-ce que la synchronisation? Qu'est-ce que la synchronisation? Jun 24, 2025 pm 08:21 PM

SynchronizationIstheprocessofcoordintinatTwoorMorEthingStostayaligned, sidigitalorphysic

See all articles