Si un programme est une collection de types, il doit avoir au moins une classe contenant une définition de fonction principale, de nom main ; l'exécution du programme commence par cette fonction. C'est elle qui invoquera éventuellement les autres fonctions. Sa définition minimale est la suivante :
public static void main(String[] args) {}
La fonction main() peut accéder à la ligne de commande passée à l'interprète de commandes pour faire exécuter le programme. Cette ligne de commande a pour objet de démarrer une Machine Virtuelle Java, de désigner la classe principale, et de spécifier la valeur d'un certain nombre de paramètres du programme . Ces paramètres sont représentés par un tableau de chaînes de caractères, conventionnellement appelé args, qui est l'unique paramètre de la fonction main(). Lors de l'invocation de main(), les éléments de ce tableau, args[0], ..., args[args.length-1], sont initialisés par les chaînes de caractères (mots séparés par des espaces) figurant sur la ligne de commande après la classe principale1.5 Par exemple, le programme (traditionnellement appelé echo) qui recopie sur la sortie standard les arguments passés sur sa ligne de commande peut être programmé ainsi :
class Echo { public static void main(String[] args) { for (int i=0; i<args.length; i++) { System.out.print(args[i] + " "); } System.out.println(); } }
Après avoir compilé cette classe, l'exécution de la commande
linux% java Echo un deux trois
provoque l'invocation de la la fonction main() de la classe Echo, et l'initialisation de son paramètre args au tableau { "un", "deux", "trois" }, puis produit sur la sortie standard (l'écran) :
un deux trois
Il est souvent nécessaire de convertir les args[i], qui sont toujours de type String, en d'autres types de données. Integer.parseInt(s) permet de convertir l'argument s, une chaîne qui est la notation d'un entier, en cet entier. Une fonction analogue Double.parseDouble(s) est disponible pour les nombres flottants. Par exemple, le programme qui additionne des entiers peut s'écrire la façon suivante.
class Add { public static void main(String[] args) { int somme = 0; for (int i=0; i < args.length ; i++) { somme = somme + Integer.parseInt(args[i]); } System.out.println(somme); } }
On pourra exécuter
linux% java Add 12 23 34
et obtenir 69 comme réponse.
La méthode main() étant statique, elle ne peut accéder aux membres des instances de sa classe. C'est pourquoi, la classe principale se trouve souvent être instanciée dans la méthode main(), dans l'unique but de pouvoir accéder aux membres non-statiques de la classe :
class Principale { void méthode() { ... } public static void main(String[] args) { Principale p = new Principale(); p.méthode(); } }
L'autre solution est de ne définir dans la classe principale que des membres statiques :
class Principale { static void méthode() { ... } public static void main(String[] args) { méthode(); } }
Rappelons que l'on accède à un membre statique d'une classe en préfixant le nom du membre par le nom de la classe. Par exemple, la classe Math, qui n'est pas destinée à être instanciée, ne comporte que des membres statiques, dont les constantes E et PI, et toutes les fonctions mathématiques usuelles ; on invoquera ainsi Math.cos(Math.PI).