Le Tutoriel de Java Reflection
1. Qu'est ce que Java Reflection?
Java utilise le mot "Java Reflection"pour nommer un API important dans la bibliothèque standard de Java. Pourquoi ce API est-il nommé de cette manière? Nous analyserons la signification de ce nommage.
Reflection est l'image de réflexion d'un objet. Par exemple, votre image dans le mirroir, ou la réflexion d'un arbre dans l'eau de lac. Le mot "Java Reflection" est simplement d'obséder d'une autre image, une autre manière d'acccès de Java.
Java est un langage orienté objet (Object-oriented). Normalement, vous devez créer un objet et accéder aux champs (field) ou appeler la méthode (method) de cet objet via l'opérateur point ( . ).
Java Reflection introduit une autre approche. Vous pouvez accéder à un champ d'un objet si vous connaissez le nom d'un tel champ ou vous pouvez appeler une méthode de l'objet si vous connaissez le nom de la méthode, les types de ses paramètres et les valeurs des paramètres à transmettre à ...
Java Reflecion vous permet d'évaluer, de modifier la structure et le comportement d'un objet à l'exécution (runtime) du programme. Et il vous donne accès à des membres private (private member) n'importe où dans l'application, ce qui n'est pas autorisé pour une approche traditionnelle.
- Java peut généralement être appelé Java Introspection (Introspection), qui peut évaluer la structure d'un objet lors de l'exécution (Runtime).
- Avec Java Reflection, le programme peut évaluer la structure d'un objet lors de l'exécution et modifier la structure et le comportement de l'objet.
2. Certaines classes ont participé aux exemples
Voici sont quelques classes qui ont participé dans les exemples de ce document.
Animal.java
package org.o7planning.tutorial.beans;
public abstract class Animal {
public String getLocation() {
return "Earth";
}
public abstract int getNumberOfLegs() ;
}
Say.java
package org.o7planning.tutorial.beans;
public interface Say {
public String say();
}
Cat.java
package org.o7planning.tutorial.beans;
public class Cat extends Animal implements Say {
public static final String SAY = "Meo meo";
public static final int NUMBER_OF_LEGS = 4;
// Private field.
private String name;
// Private field
public int age;
public Cat() {
}
public Cat(String name) {
this.name = name;
this.age = 1;
}
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return this.name;
}
// Private Method.
private void setName(String name) {
this.name = name;
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
/**
* Implements from interface Say.
*/
@Override
public String say() {
return SAY;
}
/**
* Implements from Animal.
*/
@Override
public int getNumberOfLegs() {
return NUMBER_OF_LEGS;
}
}
3. Démarrage avec un simple exemple
Voici est un simple exemple qui tri une liste des méthodes publiques d'une classe, y compris des méthodes héritées depuis de la classe mère et des interfaces.
ListMethod.java
package org.o7planning.tutorial.reflect.helloreflect;
import java.lang.reflect.Method;
public class ListMethod {
// Protected method
protected void info() {
}
public static void testMethod1() {
}
public void testMethod2() {
}
public static void main(String[] args) {
// Get a list of public methods of this class
// Include methods inherited from the parent class, or interface.
// Lấy ra danh sách các method public của class này
// Bao gồm các các method thừa kế từ class cha, hoặc các interface.
Method[] methods = ListMethod.class.getMethods();
for (Method method : methods) {
System.out.println("Method " + method.getName());
}
}
}
Le résultat de l'exécution de la classe:
Method testMethod1
Method testMethod2
Method main
Method wait
Method wait
Method wait
Method equals
Method toString
Method hashCode
Method getClass
Method notify
Method notifyAll
4. Class
Quelques méthodes importantes dans Reflection relative de la classe
L'exemple pour imprimer des informations de base de classe telles que le nom de classe, le package, le modificateur, ...
ShowClassInfo.java
package org.o7planning.tutorial.reflect.clazz;
import java.lang.reflect.Modifier;
public final class ShowClassInfo {
public static void main(String[] args) {
// Get Class object represent ShowClassInfo class.
Class<ShowClassInfo> aClass = ShowClassInfo.class;
// Print out class name, including the package name.
System.out.println("Class Name= " + aClass.getName());
// Print out simple class name (without package name).
System.out.println("Simple Class Name= " + aClass.getSimpleName());
// Package info
Package pkg = aClass.getPackage();
System.out.println("Package Name = " + pkg.getName());
// Modifier
int modifiers = aClass.getModifiers();
boolean isPublic = Modifier.isPublic(modifiers);
boolean isInterface = Modifier.isInterface(modifiers);
boolean isAbstract = Modifier.isAbstract(modifiers);
boolean isFinal = Modifier.isFinal(modifiers);
// true
System.out.println("Is Public? " + isPublic);
// true
System.out.println("Is Final? " + isFinal);
// false
System.out.println("Is Interface? " + isInterface);
// false
System.out.println("Is Abstract? " + isAbstract);
}
}
Le résultat de l'exécution de l'exemple
Class Name= org.o7planning.tutorial.reflect.clazz.ShowClassInfo
Simple Class Name= ShowClassInfo
Package Name = org.o7planning.tutorial.reflect.clazz
Is Public? true
Is Final? true
Is Interface? false
Is Abstract? false
L'exemple pour écrire des informations de la classe Cat, telles que le nom de la classe et les interfaces que cette classe implémente.
ShowClassCatInfo.java
package org.o7planning.tutorial.reflect.clazz;
import org.o7planning.tutorial.beans.Cat;
public class ShowClassCatInfo {
public static void main(String[] args) {
// The Class object represent Cat class
Class<Cat> aClass = Cat.class;
// Class name
System.out.println("Simple Class Name = " + aClass.getSimpleName());
// Get the Class object represent parent of Cat class
Class<?> aSuperClass = aClass.getSuperclass();
System.out.println("Simple Class Name of Super class = "
+ aSuperClass.getSimpleName());
// Determines the interfaces implemented by the class
// or interface represented by this object.
Class<?>[] itfClasses = aClass.getInterfaces();
for (Class<?> itfClass : itfClasses) {
System.out.println("Interface: " + itfClass.getSimpleName());
}
}
}
Running the example:
Simple Class Name = Cat
Simple Class Name of Super class = Animal
Interface: Say
L'exemple de récupération d'informations du constructeur, de la méthode, du domaine de classe (public uniquement), y compris les méthodes publiques, domaine public, hérité de la classe mère, les interfaces.
ShowMemberInfo.java
package org.o7planning.tutorial.reflect.clazz;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.o7planning.tutorial.beans.Cat;
public class ShowMemberInfo {
public static void main(String[] args) {
// Get object represent Cat class.
Class<Cat> aClass = Cat.class;
// Get Constructor array of Cat.
Constructor<?>[] constructors = aClass.getConstructors();
System.out.println(" ==== CONSTRUCTORs: ===== ");
for (Constructor<?> constructor : constructors) {
System.out.println("Constructor: " + constructor.getName());
}
// Get a list of public method of Cat
// Include the methods inherited from the parent class and the interfaces
Method[] methods = aClass.getMethods();
System.out.println(" ==== METHODs: ====== ");
for (Method method : methods) {
System.out.println("Method: " + method.getName());
}
// Get the list of the public fields
// Include the fields inherited from the parent class, and the interfaces
Field[] fields = aClass.getFields();
System.out.println(" ==== FIELDs: ====== ");
for (Field field : fields) {
System.out.println("Field: " + field.getName());
}
}
}
Résultat de l'exécution de l'exemple:
==== CONSTRUCTORs: =====
Constructor: org.o7planning.tutorial.beans.Cat
Constructor: org.o7planning.tutorial.beans.Cat
Constructor: org.o7planning.tutorial.beans.Cat
==== METHODs: ======
Method: getAge
Method: setAge
Method: say
Method: getNumberOfLegs
Method: getName
Method: getLocation
Method: wait
Method: wait
Method: wait
Method: equals
Method: toString
Method: hashCode
Method: getClass
Method: notify
Method: notifyAll
==== FIELDs: ======
Field: SAY
Field: NUMBER_OF_LEGS
Field: age
5. Constructor
Par exemple, prendre un constructeur (constructor) avec les paramètres spécifiés. Et imprimer des informations sur ce constructeur (constructor).
ConstructorExample.java
package org.o7planning.tutorial.reflect.constructor;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import org.o7planning.tutorial.beans.Cat;
public class ConstructorExample {
public static void main(String[] args) throws NoSuchMethodException,
SecurityException, InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
// Get Class object represent Cat class.
Class<Cat> aClass = Cat.class;
// Get the Constructor object of the public constructor
// that matches the specified parameterTypes
Constructor<?> constructor = aClass.getConstructor(String.class,
int.class);
// Get parameter array of this constructor.
Class<?>[] paramClasses = constructor.getParameterTypes();
for (Class<?> paramClass : paramClasses) {
System.out.println("Param: " + paramClass.getSimpleName());
}
// Initialize the object in the usual way
Cat tom = new Cat("Tom", 3);
System.out
.println("Cat 1: " + tom.getName() + ", age =" + tom.getAge());
// Using Java reflection to create object
Cat tom2 = (Cat) constructor.newInstance("Tom", 2);
System.out.println("Cat 2: " + tom.getName() + ", age ="
+ tom2.getAge());
}
}
Résultats de l'exécution de la classe:
Param: String
Param: int
Cat 1: Tom, age =3
Cat 2: Tom, age =2
6. Field
L'exemple ci- dessous récupère field avec le nom spécifié.
FieldExample.java
package org.o7planning.tutorial.reflect.field;
import java.lang.reflect.Field;
import org.o7planning.tutorial.beans.Cat;
public class FieldExample {
public static void main(String[] args) throws NoSuchFieldException,
SecurityException, IllegalArgumentException, IllegalAccessException {
// Get Class object represent Cat class
Class<Cat> aClass = Cat.class;
// Get Field object represent field 'NUMBER_OF_LEGS'.
Field field = aClass.getField("NUMBER_OF_LEGS");
Class<?> fieldType = field.getType();
System.out.println("Field type: " + fieldType.getSimpleName());
Field ageField = aClass.getField("age");
Cat tom = new Cat("Tom", 5);
// Returns the value of the field represented by this Field,
// on the specified object.
Integer age = (Integer) ageField.get(tom);
System.out.println("Age = " + age);
// Sets the field represented by this Field object on
// the specified object argument to the specified new value.
ageField.set(tom, 7);
System.out.println("New Age = "+ tom.getAge());
}
}
Résultat de l'exécution de la classe:
Field type: int
Age = 5
New Age = 7
7. Method
Par exemple, en prenant une méthode avec le nom et les paramètres spécifiés. Imprimez les informations sur cette méthode, telles que le type de retour, une liste de paramètres, ...
MethodExample.java
package org.o7planning.tutorial.reflect.method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.o7planning.tutorial.beans.Cat;
public class MethodExample {
public static void main(String[] args) throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
// Class object represent Cat class
Class<Cat> aClass = Cat.class;
// Method object represent getAge() method.
Method getAgeMethod = aClass.getMethod("getAge");
// return type of method.
Class<?> returnType= getAgeMethod.getReturnType();
System.out.println("Return type of getAge: "+ returnType.getSimpleName());
Cat tom = new Cat("Tom", 7);
// Call method 'getAge' way Reflect
// This is equivalent to calling: tom.getAge()
int age = (int) getAgeMethod.invoke(tom);
System.out.println("Age = " + age);
// Method object represent setAge(int) method of Cat class.
Method setAgeMethod = aClass.getMethod("setAge", int.class);
// Call method setAge(int) way Reflect
// This is equivalent to calling: tom.setAge(5)
setAgeMethod.invoke(tom, 5);
System.out.println("New Age = " + tom.getAge());
}
}
Résultats de l'exécution de l'exemple:
Return type of getAge: int
Age = 7
New Age = 5
8. Des méthodes getter et setter
L'exemple ci-dessous énumère les méthodes public setter et les méthodes public getter de la classe.
GetSetExample.java
package org.o7planning.tutorial.reflect.getset;
import java.lang.reflect.Method;
import org.o7planning.tutorial.beans.Cat;
public class GetSetExample {
// Method is getter if names start with get, and no parameters.
public static boolean isGetter(Method method) {
if (!method.getName().startsWith("get")) {
return false;
}
if (method.getParameterTypes().length != 0) {
return false;
}
if (void.class.equals(method.getReturnType())) {
return false;
}
return true;
}
// Method is setter if names start with set, and only one parameter.
public static boolean isSetter(Method method) {
if (!method.getName().startsWith("set")) {
return false;
}
if (method.getParameterTypes().length != 1) {
return false;
}
return true;
}
public static void main(String[] args) {
// Class object represet Cat class
Class<Cat> aClass = Cat.class;
// public methods
Method[] methods = aClass.getMethods();
for (Method method : methods) {
boolean isSetter = isSetter(method);
boolean isGetter = isGetter(method);
System.out.println("Method: " + method.getName());
System.out.println(" - Is Setter? " + isSetter);
System.out.println(" - Is Getter? " + isGetter);
}
}
}
Résultats de l'exécution de l'exemple:
Method: getName
- Is Setter? false
- Is Getter? true
Method: getNumberOfLegs
- Is Setter? false
- Is Getter? true
Method: getAge
- Is Setter? false
- Is Getter? true
Method: setAge
- Is Setter? true
- Is Getter? false
Method: say
- Is Setter? false
- Is Getter? false
Method: getLocation
- Is Setter? false
- Is Getter? true
Method: wait
- Is Setter? false
- Is Getter? false
Method: wait
- Is Setter? false
- Is Getter? false
Method: wait
- Is Setter? false
- Is Getter? false
Method: equals
- Is Setter? false
- Is Getter? false
Method: toString
- Is Setter? false
- Is Getter? false
Method: hashCode
- Is Setter? false
- Is Getter? false
Method: getClass
- Is Setter? false
- Is Getter? true
Method: notify
- Is Setter? false
- Is Getter? false
Method: notifyAll
- Is Setter? false
- Is Getter? false
9. Accéder des méthodes private,des champs
Vous ne pouvez pas accéder à la méthode ou au champ lorsqu'il est private de la manière habituelle, le compilateur java ne l'autorise pas. Mais avec Java Reflection, c'est absolument possible.
AccessPrivateFieldExample.java
package org.o7planning.tutorial.reflect.privateaccess;
import java.lang.reflect.Field;
import org.o7planning.tutorial.beans.Cat;
public class AccessPrivateFieldExample {
public static void main(String[] args) throws IllegalArgumentException,
IllegalAccessException, NoSuchFieldException, SecurityException {
// Class object represent Cat class
Class<Cat> aClass = Cat.class;
// Class.getField(String) get public field only.
// Use Class.getDeclaredField(String):
// Get the Field object of field declared in class.
Field private_nameField = aClass.getDeclaredField("name");
// Allows for access to private field.
// Avoid IllegalAccessException
private_nameField.setAccessible(true);
Cat tom = new Cat("Tom");
String fieldValue = (String) private_nameField.get(tom);
System.out.println("Value field name = " + fieldValue);
// Set new valud for 'name' field.
private_nameField.set(tom, "Tom Cat");
System.out.println("New name = " + tom.getName());
}
}
Résultats de l'exécution de l'exemple:
Value field name = Tom
New name = Tom Cat
L'exemple suivant, accéder à une méthode private.
AccessPrivateMethodExample.java
package org.o7planning.tutorial.reflect.privateaccess;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.o7planning.tutorial.beans.Cat;
public class AccessPrivateMethodExample {
public static void main(String[] args) throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
// Class object represent Cat class.
Class<Cat> aClass = Cat.class;
// Class.getMethod(String) get public method only.
// Use Class.getDeclaredMethod(String):
// Get the Method object of method declared in class.
Method private_setNameMethod = aClass.getDeclaredMethod("setName",
String.class);
// Allows for access to private method.
// Avoid IllegalAccessException
private_setNameMethod.setAccessible(true);
Cat tom = new Cat("Tom");
// Call private method
private_setNameMethod.invoke(tom, "Tom Cat");
System.out.println("New name = " + tom.getName());
}
}
Résultat de l'exécution de l'exemple:
New name = Tom Cat
10. Annotation
MyAnnotation.java
package org.o7planning.tutorial.reflect.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// Annotation can be used at runtime.
@Retention(RetentionPolicy.RUNTIME)
// Use for class, interface, method, field, parameter.
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD,
ElementType.PARAMETER })
public @interface MyAnnotation {
String name();
String value() default "";
}
Un exemple d' Annotation avec classe:
ClassAnnotationExample.java
package org.o7planning.tutorial.reflect.annotation;
import java.lang.annotation.Annotation;
@MyAnnotation(name = "Table", value = "Employee")
public class ClassAnnotationExample {
public static void main(String[] args) {
Class<?> aClass = ClassAnnotationExample.class;
// Get array of the Annotation of class
Annotation[] annotations = aClass.getAnnotations();
for (Annotation ann : annotations) {
System.out.println("Annotation: " + ann.annotationType().getSimpleName());
}
// Or More specific
Annotation ann = aClass.getAnnotation(MyAnnotation.class);
MyAnnotation myAnn = (MyAnnotation) ann;
System.out.println("Name = " + myAnn.name());
System.out.println("Value = " + myAnn.value());
}
}
Résultat de l'exécution de l'exemple:
Annotation: MyAnnotation
Name = Table
Value = Employee
Un exemple d'Annotation avec Champ (Field) & Méthode (Method):
FieldMethodAnnotationExample.java
package org.o7planning.tutorial.reflect.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class FieldMethodAnnotationExample {
@MyAnnotation(name = "My Field")
private int myField;
@MyAnnotation(name = "My Method", value = "My Method Value")
protected void myMethod(String str) {
}
public static void main(String[] args) throws NoSuchFieldException,
SecurityException, NoSuchMethodException {
Class<?> aClass = FieldMethodAnnotationExample.class;
//
System.out.println(" == FIELD == ");
Field field = aClass.getDeclaredField("myField");
// Get array of Annotation of field
Annotation[] fieldAnns = field.getAnnotations();
for (Annotation methodAnn : fieldAnns) {
System.out.println("Annotation: "
+ methodAnn.annotationType().getSimpleName());
}
// Or more specific
Annotation fieldAnn = field.getAnnotation(MyAnnotation.class);
MyAnnotation myAnn1 = (MyAnnotation) fieldAnn;
System.out.println("Name = " + myAnn1.name());
System.out.println("Value = " + myAnn1.value());
// Similar for method ...
System.out.println(" == METHOD == ");
Method method = aClass.getDeclaredMethod("myMethod", String.class);
// Get array of Annotation of method
Annotation[] methodAnns = method.getAnnotations();
for (Annotation methodAnn : methodAnns) {
System.out.println("Annotation: "
+ methodAnn.annotationType().getSimpleName());
}
// For more specific
Annotation methodAnn = method.getAnnotation(MyAnnotation.class);
MyAnnotation myAnn2 = (MyAnnotation) methodAnn;
System.out.println("Name = " + myAnn2.name());
System.out.println("Value = " + myAnn2.value());
}
}
Résultat de l'exécution de l'exemple:
== FIELD ==
Annotation: MyAnnotation
Name = My Field
Value =
== METHOD ==
Annotation: MyAnnotation
Name = My Method
Value = My Method Value
Un exemple d'Annotation avec le paramètre de la méthode:
ParameterAnnotationExample.java
package org.o7planning.tutorial.reflect.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class ParameterAnnotationExample {
// For example, a method with annotations in parameters.
protected void doSomething(int jobType,
@MyAnnotation(name = "Table", value = "Employee") String info) {
}
public static void main(String[] args) throws NoSuchMethodException,
SecurityException {
Class<?> aClass = ParameterAnnotationExample.class;
// Get Method object of doSomething(int,String) method.
Method method = aClass.getDeclaredMethod("doSomething", int.class,
String.class);
// Get parameters list of method
Class<?>[] parameterTypes = method.getParameterTypes();
for (Class<?> parameterType : parameterTypes) {
System.out.println("Parametete Type: "
+ parameterType.getSimpleName());
}
System.out.println(" ---- ");
// Returns an array of arrays of Annotations that
// represent the annotations on the formal parameters
Annotation[][] annotationss = method.getParameterAnnotations();
// Get Annotation list of parameter index 1.
Annotation[] annotations = annotationss[1];
for (Annotation ann : annotations) {
System.out.println("Annotation: "
+ ann.annotationType().getSimpleName());
}
}
}
Parametete Type: int
Parametete Type: String
----
Annotation: MyAnnotation
Java Basic
- Personnaliser le compilateur Java pour traiter votre annotation (Annotation Processing Tool)
- Programmation Java pour l'équipe utilisant Eclipse et SVN
- Le Tutoriel de Java WeakReference
- Le Tutoriel de Java PhantomReference
- Tutoriel sur la compression et la décompression Java
- Configuration d'Eclipse pour utiliser le JDK au lieu de JRE
- Méthodes Java String.format() et printf()
- Syntaxe et nouvelles fonctionnalités de Java 8
- Expression régulière en Java
- Tutoriel de programmation Java multithreading
- Bibliothèques de pilotes JDBC pour différents types de bases de données en Java
- Tutoriel Java JDBC
- Obtenir des valeurs de colonne automatiquement incrémentées lors de l'insertion d'un enregistrement à l'aide de JDBC
- Le Tutoriel de Java Stream
- Le Tutoriel de Java Functional Interface
- Introduction à Raspberry Pi
- Le Tutoriel de Java Predicate
- Classe abstraite et interface en Java
- Modificateurs d'accès en Java
- Le Tutoriel de Java Enum
- Le Tutoriel de Java Annotation
- Comparer et trier en Java
- Le Tutoriel de Java String, StringBuffer et StringBuilder
- Tutoriel de gestion des exceptions Java
- Le Tutoriel de Java Generics
- Manipulation de fichiers et de répertoires en Java
- Le Tutoriel de Java BiPredicate
- Le Tutoriel de Java Consumer
- Le Tutoriel de Java BiConsumer
- Qu'est-ce qui est nécessaire pour commencer avec Java?
- L'histoire de Java et la différence entre Oracle JDK et OpenJDK
- Installer Java sur Windows
- Installer Java sur Ubuntu
- Installer OpenJDK sur Ubuntu
- Installer Eclipse
- Installer Eclipse sur Ubuntu
- Le Tutoriel Java pour débutant
- Histoire des bits et des bytes en informatique
- Types de données dans Java
- Opérations sur les bits
- Le Tutoriel de instruction Java If else
- Le Tutoriel de instruction Java Switch
- Les Boucles en Java
- Les Tableaux (Array) en Java
- JDK Javadoc au format CHM
- Héritage et polymorphisme en Java
- Le Tutoriel de Java Function
- Le Tutoriel de Java BiFunction
- Exemple de Java encoding et decoding utilisant Apache Base64
- Le Tutoriel de Java Reflection
- Invocation de méthode à distance en Java
- Le Tutoriel de Java Socket
- Quelle plate-forme devez-vous choisir pour développer des applications de bureau Java?
- Le Tutoriel de Java Commons IO
- Le Tutoriel de Java Commons Email
- Le Tutoriel de Java Commons Logging
- Comprendre Java System.identityHashCode, Object.hashCode et Object.equals
- Le Tutoriel de Java SoftReference
- Le Tutoriel de Java Supplier
- Programmation orientée aspect Java avec AspectJ (AOP)
Show More
- Tutoriels de programmation Java Servlet/JSP
- Tutoriels de Java Collections Framework
- Tutoriels Java API pour HTML & XML
- Tutoriels Java IO
- Tutoriels Java Date Time
- Tutoriels Spring Boot
- Tutoriels Maven
- Tutoriels Gradle
- Tutoriels Java Web Service
- Tutoriels de programmation Java SWT
- Tutoriels de JavaFX
- Tutoriels Java Oracle ADF
- Tutoriels Struts2
- Tutoriels Spring Cloud