Paquets Java
Source :
Usemynotes Cet article vous aidera à mieux comprendre les packages en Java, à comprendre leur objectif et comment les implémenter.
Que sont les packages en Java
Un package en Java est un moyen de regrouper un groupe de classes, d'interfaces et de sous-packages. Les packages sont utilisés pour créer des groupes de classes, d'interfaces, d'énumérations associées, etc.
Les sous-packages sont des packages qui se trouvent dans un autre package. Ils ne sont pas importés par défaut, mais vous pouvez les importer manuellement si nécessaire. La spécification d'accès n'est pas fournie aux membres individuels d'un sous-paquet ; ils sont traités comme des packages distincts.
Quelques types de packages en Java :
- java.lang - est fourni avec Java par défaut.
- java.io - contient des classes, des méthodes et d'autres éléments liés aux entrées/sorties.
Pourquoi les forfaits sont-ils nécessaires ?
- Pour éviter les conflits de noms.
- Pour fournir un accès contrôlé.
- Pour réaliser l’encapsulation des données.
Comment créer un package en Java ?
Créons un package appelé
ordinateur . Généralement, le nom du package est écrit en lettres minuscules. Ceci est fait uniquement pour éviter les conflits de noms avec les noms de classe. Nous créerons également une interface appelée
Pluggable , qui sera située dans le package
informatique .
package computer;
interface Pluggable {
public void pluggedIn();
public void pluggedOut();
}
Nous allons maintenant créer une classe appelée
PenDrive qui implémentera l'interface ci-dessus.
package computer;
public class PenDrive implements Pluggable {
int storage = 64;
public void pluggedIn () {
System.out.println("Pen Drive is connected");
}
public void pluggedOut () {
System.out.println("Pen Drive is removed");
}
public int storage() {
return storage;
}
public static void main(String args[]) {
PenDrive p = new PenDrive ();
p.pluggedIn();
System.out.println("Pen Drive Storage: " + p.storage());
p.pluggedOut();
}
}
Comment créer une hiérarchie de packages en Java ?
Lors de la formation d'une hiérarchie, les packages en Java sont nommés dans l'ordre inverse. Cela les rend très similaires aux répertoires ou aux dossiers. Tout comme sur un ordinateur personnel, où un dossier peut contenir un ou plusieurs sous-dossiers, il en va de même pour les packages Java. Regardons un package nommé
Asia.India.Kolkata . Ce sont tous des dossiers existants, mais si l’on considère la géographie, il est clair que Calcutta est en Inde et que l’Inde est en Asie. L’objectif principal d’une hiérarchie est de faciliter la recherche des classes.
Types de packages en Java
Forfaits intégrés
Les packages intégrés sont des packages constitués d'un grand nombre de classes intégrées qui font partie de l'API Java. Ces forfaits comprennent :
- java.util - Ce package contient un nombre fini de classes utilitaires utilisées pour implémenter des structures de données telles que des listes chaînées, des ensembles, etc. Il prend également en charge les opérations de date et d'heure et bien plus encore.
- java.net - Il contient des classes utilisées pour les opérations réseau.
Packages définis par l'utilisateur
Les packages définis par l'utilisateur sont appelés packages utilisateur. L'utilisateur peut créer manuellement un package et contenir autant de classes qu'il le souhaite.
Comment accéder à un package depuis un autre package ?
Vous pouvez accéder à un package à partir d’un autre package de trois manières simples :
- Utiliser un astérisque dans une instruction d'importation
Le caractère astérisque (
* ) est utilisé pour représenter « toutes choses » en Java. En l'utilisant, nous pouvons importer tout ce qui se trouve dans un sous-paquet d'un package.
Exemple : considérons un package nommé
tools . Si nous voulons importer tout ce qui se trouve dans ce package, nous devons utiliser l'instruction d'importation telle que :
import tools.*;
- Utilisation de l'importation package.ClassName ;
Mentionner le nom de la classe dans un package est un moyen efficace d'importer uniquement les classes dont vous avez besoin dans votre programme, évitant ainsi d'importer des classes inutiles.
Exemple : considérons un package nommé
books . Si nous souhaitons uniquement importer une classe ou une interface spécifique à partir de celle-ci (nous examinerons la classe
Pages ), nous pouvons importer uniquement cela en utilisant :
import book.Pages;
- En utilisant votre nom complet
Il existe un moyen d'utiliser directement un package Java ou ses classes en utilisant leur nom complet. De cette façon, vous n'avez pas besoin d'importer le package et pouvez l'utiliser directement dans le programme.
Exemple:
java.awt.List aSimpleList = new java.awt.List();
Taille de lot par défaut en Java
Par défaut, Java importe le package
java.lang . Il contient de nombreuses classes couramment utilisées dans des programmes Java simples tels que
String ,
Integer et autres. L'une des classes les plus importantes est la classe
Object , qui se trouve également dans le package
java.lang . La taille de ce package est basée sur ses composants : 8 interfaces, 37 classes, 3 énumérations, 27 exceptions, 23 types d'erreurs et 5 types d'annotations.
Méthodes Java Thread-Safe pour les débutants
Source :
Medium Grâce à cet article, vous pouvez en apprendre davantage sur le fonctionnement des méthodes thread-safe en Java. ![Pause café #165. Packages en Java. Méthodes thread-safe pour les débutants - 2]()
J'ai constaté que de nombreux développeurs Java juniors/moyens comprennent mal comment les méthodes thread-safe devraient fonctionner dans des projets réels. Et comme nous travaillons généralement dans un environnement multithread, leur utilisation correcte est très importante. Une méthode thread-safe est une méthode qui peut être appelée simultanément à partir de plusieurs threads sans affecter l’état des données de chacun. Une compréhension insuffisante de ce concept conduit à des bugs difficiles à trouver et à corriger. Pour éviter de telles erreurs, regardons des exemples.
Exemple 1:
public static int countLetters(String input) {
int counter = 0;
for (Character c : input.toCharArray()) {
if (Character.isAlphabetic(c)) {
counter++;
}
}
return counter;
}
- La méthode countLetters est statique, elle renvoie une valeur int et accepte un paramètre chaîne en entrée.
- Un compteur de variable primitif est créé à l'intérieur de la méthode, puis la boucle parcourt les caractères de la chaîne d'entrée et incrémente le compteur de variable à chaque fois qu'un caractère de lettre est rencontré.
Cette méthode est-elle thread-safe ? De nombreux développeurs disent non, car dans ce cas, nous avons une opération d'incrémentation qui n'est pas thread-safe. Voyons cela. Dans le modèle de mémoire Java, nous avons une pile et un tas. Chaque thread possède sa propre pile et tous les threads partagent le même tas. À cet égard, les données de la pile sont toujours thread-safe, mais pas les données du tas. La pile stocke les primitives et les références d'objets. Le tas contient les objets eux-mêmes. Cela signifie que dans cet exemple de code, chaque thread stocke
son propre compteur de variables sur la pile et n'a aucun effet sur les données des autres threads, la méthode est donc
thread-safe .
Notez que la valeur String d'entrée est également un objet, mais les wrappers String et primitifs ( Integer , Long , Double , Boolean et ainsi de suite) sont thread-safe car ils sont immuables.
Exemple n°2 :
public static int countLetters2(String input) {
List<Character> listCounter = new ArrayList<>();
for (Character c : input.toCharArray()) {
if (Character.isAlphabetic(c)) {
listCounter.add(c);
}
}
return listCounter.size();
}
Ce code utilisait la même logique que le premier exemple, mais utilisait un objet
List au lieu d'une variable int primitive . De la partie précédente, nous savons que les objets en Java sont stockés dans un tas et que
List est un objet. Nous savons également que la pile stocke les références aux objets sur le tas. Dans l'exemple n°2, chaque thread crée un nouvel objet
ArrayList : et la variable
listCounter stocke une référence à son objet sur le tas, donc aucun autre thread ne peut modifier cet objet.
List<Character> listCounter = new ArrayList<>();
Cela signifie que cette méthode est thread-safe.
Exemple n°3 :
public class CounterUtil {
List<Character> listCounter = new ArrayList<>();
public int countLetters3(String input) {
for (Character c : input.toCharArray()) {
if (Character.isAlphabetic(c)) {
listCounter.add(c);
}
}
return listCounter.size();
}
}
Dans cet exemple, nous avons une classe singleton (c'est important)
CounterUtil avec une variable globale
listCounter . Cette variable est créée en même temps que l'instance singleton. Lorsque plusieurs threads appellent la méthode
countChars3 , ils utilisent tous la même variable globale
listCounter , qui stocke une référence au même objet sur le tas, et les threads s'influenceront mutuellement. Nous pouvons donc conclure que cette méthode n’est pas thread-safe. Et même si nous changeons
List<Character> listCounter en une variable primitive
int counter , elle ne sera pas non plus thread-safe car tous les threads utiliseront la même variable primitive.
Dernier exemple :
public static int countLetters4(List<Character> inputList) {
List<Character> listCounter = new ArrayList<>();
for (Character c : inputList) {
if (Character.isAlphabetic(c)) {
listCounter.add(c);
}
}
return listCounter.size();
}
La méthode
countLetters4 accepte une liste de caractères au lieu d'un paramètre
String . Ici, nous
ne pouvons pas garantir que cette méthode est thread-safe. Pourquoi? Parce que nous ne pouvons pas être sûrs de la manière dont les développeurs utiliseront cette méthode. Si un autre thread extérieur modifie les données dans
inputList en même temps que notre méthode
counterLetters4 , cela pourrait affecter le résultat final.
Conclusion
Nous n'avons examiné que quatre exemples, et ils ne couvrent pas tous les aspects de la sécurité des threads dans les projets Java, mais ils constituent un bon point de départ. La prochaine fois que vous verrez une méthode dans votre code, demandez-vous : « Cette méthode est-elle thread-safe ? » Et très bientôt, vous comprendrez clairement la réponse.
GO TO FULL VERSION