Je recherche une réponse claire, concise et précise.
Idéalement comme réponse réelle, bien que les liens vers de bonnes explications soient les bienvenus.
Je recherche une réponse claire, concise et précise.
Idéalement comme réponse réelle, bien que les liens vers de bonnes explications soient les bienvenus.
language-but-not-type-agnostic
?static-language-agnostic
? Je ne suis pas sûr que SO ait besoin de la distinction; pourrait être une bonne question pour meta cependant.Réponses:
Les valeurs encadrées sont des structures de données qui sont des wrappers minimaux autour des types primitifs *. Les valeurs encadrées sont généralement stockées sous forme de pointeurs vers des objets sur le tas .
Ainsi, les valeurs encadrées utilisent plus de mémoire et nécessitent au minimum deux recherches de mémoire pour y accéder: une fois pour obtenir le pointeur et une autre pour suivre ce pointeur vers la primitive. De toute évidence, ce n'est pas le genre de chose que vous voulez dans vos boucles intérieures. D'un autre côté, les valeurs encadrées fonctionnent généralement mieux avec les autres types du système. Puisqu'il s'agit de structures de données de première classe dans le langage, elles ont les métadonnées et la structure attendues des autres structures de données.
Dans Java et Haskell, les collections génériques ne peuvent pas contenir de valeurs sans boîte. Les collections génériques dans .NET peuvent contenir des valeurs sans boîte sans pénalités. Lorsque les génériques de Java sont uniquement utilisés pour la vérification de type au moment de la compilation, .NET générera des classes spécifiques pour chaque type générique instancié au moment de l'exécution .
Java et Haskell ont des tableaux sans boîte, mais ils sont nettement moins pratiques que les autres collections. Cependant, lorsque des performances de pointe sont nécessaires, cela vaut un petit inconvénient pour éviter les frais généraux liés à la boxe et au déballage.
* Pour cette discussion, une valeur primitive est toute valeur qui peut être stockée sur la pile d'appels , plutôt que stockée sous forme de pointeur vers une valeur sur le tas. Souvent, il ne s'agit que des types de machine (ints, floats, etc.), des structures et parfois des tableaux de taille statique. .NET-land les appelle des types valeur (par opposition aux types référence). Les gens de Java les appellent des types primitifs. Les Haskellions les appellent simplement sans boîte.
** Je me concentre également sur Java, Haskell et C # dans cette réponse, car c'est ce que je sais. Pour ce que ça vaut, Python, Ruby et Javascript ont tous des valeurs exclusivement encadrées. Ceci est également connu sous le nom d'approche «Tout est un objet» ***.
*** Mise en garde: un compilateur / JIT suffisamment avancé peut dans certains cas détecter qu'une valeur qui est encadrée sémantiquement lors de la consultation de la source, peut en toute sécurité être une valeur sans boîte au moment de l'exécution. En substance, grâce à de brillants implémenteurs de langage, vos boîtes sont parfois gratuites.
la source
à partir de C # 3.0 En bref :
la source
Le boxing & unboxing est le processus de conversion d'une valeur primitive en une classe wrapper orientée objet (boxing), ou de conversion d'une valeur d'une classe wrapper orientée objet vers la valeur primitive (unboxing).
Par exemple, en java, vous devrez peut-être convertir une
int
valeur en unInteger
(boxing) si vous souhaitez la stocker dans unCollection
car les primitives ne peuvent pas être stockées dans unCollection
, uniquement des objets. Mais lorsque vous souhaitez le récupérer,Collection
vous voudrez peut-être obtenir la valeur en tant que anint
et non pasInteger
pour le déballer.La boxe et le déballage ne sont pas intrinsèquement mauvais , mais c'est un compromis. Selon l'implémentation du langage, cela peut être plus lent et plus gourmand en mémoire que la simple utilisation de primitives. Cependant, cela peut également vous permettre d'utiliser des structures de données de niveau supérieur et d'obtenir une plus grande flexibilité dans votre code.
Ces jours-ci, il est le plus souvent discuté dans le contexte de la fonctionnalité "autoboxing / autounboxing" de Java (et d'autres langages). Voici une explication java centrée de l'autoboxing .
la source
Dans .Net:
Souvent, vous ne pouvez pas vous fier au type de variable qu'une fonction consommera, vous devez donc utiliser une variable objet qui s'étend du plus petit dénominateur commun - dans .Net c'est
object
.Cependant
object
est une classe et stocke son contenu comme référence.Bien que les deux contiennent les mêmes informations, la deuxième liste est plus longue et plus lente. Chaque valeur de la deuxième liste est en fait une référence à un
object
qui contient leint
.Ceci est appelé boxed car le
int
est enveloppé par leobject
. Quand ilint
est renvoyé, il est déballé - reconverti à sa valeur.Pour les types valeur (c'est-à-dire tous
structs
), cela est lent et utilise potentiellement beaucoup plus d'espace.Pour les types de référence (c'est-à-dire tous
classes
), c'est bien moins un problème, car ils sont de toute façon stockés comme référence.Un autre problème avec un type de valeur encadré est qu'il n'est pas évident que vous traitez avec la boîte plutôt qu'avec la valeur. Lorsque vous comparez deux,
structs
vous comparez des valeurs, mais lorsque vous comparez deux, vous comparezclasses
(par défaut) la référence - c'est-à-dire que ce sont les mêmes instances?Cela peut être déroutant lorsqu'il s'agit de types de valeur encadrés:
Il est facile de contourner:
Cependant, c'est une autre chose à laquelle il faut faire attention lorsqu'il s'agit de valeurs encadrées.
la source
Object
n'implémente pas l'opérateur d'égalité, mais les types de classe peuvent être comparés à l'Is
opérateur; inversement,Int32
peut être utilisé avec l'opérateur d'égalité, mais pasIs
. Cette distinction rend beaucoup plus clair le type de comparaison effectué.Boxing
est le processus de conversion d'un type valeur en type référence. Alors queUnboxing
c'est la conversion d'un type de référence en un type de valeur.Types de valeur sont:
int
,char
etstructures
,enumerations
. Types de référence sont:Classes
,interfaces
,arrays
,strings
etobjects
la source
Les collections génériques .NET FCL:
ont tous été conçus pour surmonter les problèmes de performances de la boxe et du déballage dans les implémentations de collection précédentes.
Pour plus d'informations, consultez le chapitre 16, CLR via C # (2e édition) .
la source
La boxe et le déballage facilitent le traitement des types de valeurs comme des objets. Boxing signifie convertir une valeur en une instance du type de référence d'objet. Par exemple,
Int
est une classe etint
est un type de données. La conversionint
enInt
est une illustration de la boxe, alors que la conversionInt
enint
est un déballage. Le concept aide dans le garbage collection, Unboxing, d'autre part, convertit le type d'objet en type valeur.la source
var ii = 123; typeof ii
renvoienumber
.var iiObj = new Number(123); typeof iiObj
revientobject
.typeof ii + iiObj
revientnumber
. C'est donc l'équivalent javascript de la boxe. La valeur iiObj a été automatiquement convertie en un nombre primitif (sans boîte) afin d'effectuer l'arithmétique et renvoyer une valeur sans boîte.Comme toute autre chose, la boxe automatique peut être problématique si elle n'est pas utilisée avec précaution. Le classique est de se retrouver avec une NullPointerException et de ne pas pouvoir la retrouver. Même avec un débogueur. Essaye ça:
la source
i
est initialisée prématurément. Soit faites-en une déclaration vide (Integer i;
) pour que le compilateur puisse signaler que vous avez oublié de l'initialiser, soit attendez de la déclarer jusqu'à ce que vous connaissiez sa valeur.