Zoeken…


Opmerkingen

De opdracht javac wordt gebruikt voor het compileren van Java-bronbestanden naar bytecode-bestanden. Bytecode-bestanden zijn platformonafhankelijk. Dit betekent dat u uw code kunt compileren op één soort hardware en besturingssysteem en de code vervolgens kunt uitvoeren op elk ander platform dat Java ondersteunt.

De opdracht javac is opgenomen in de JDK-distributies (Java Development Kit).

De Java-compiler en de rest van de standaard Java-toolchain plaatsen de volgende beperkingen op de code:

  • Broncode wordt bewaard in bestanden met het achtervoegsel ".java"
  • Bytecodes worden bewaard in bestanden met het achtervoegsel ".class"
  • Voor bron- en bytecode-bestanden in het bestandssysteem moeten de padnamen van het bestand de naamgeving van het pakket en de klasse weergeven.

Opmerking: De javac compiler moet niet worden verward met de Just in Time (JIT) -compiler die bytecodes compileert naar native code.

Het commando 'javac' - aan de slag

Eenvoudig voorbeeld

Ervan uitgaande dat de "HelloWorld.java" de volgende Java-bron bevat:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello world!");
    }
}

(Raadpleeg voor meer informatie over de bovenstaande code Aan de slag met Java Language .)

We kunnen het bovenstaande bestand compileren met deze opdracht:

$ javac HelloWorld.java 

Dit produceert een bestand met de naam "HelloWorld.class", dat we vervolgens als volgt kunnen uitvoeren:

$ java HelloWorld
Hello world!

De belangrijkste aandachtspunten in dit voorbeeld zijn:

  1. De bronbestandsnaam "HelloWorld.java" moet overeenkomen met de klassenaam in het bronbestand ... dat is HelloWorld . Als ze niet overeenkomen, krijgt u een compilatiefout.
  2. De bytecode-bestandsnaam "HelloWorld.class" komt overeen met de klassenaam. Als u de naam "HelloWorld.class" zou hernoemen, krijgt u een foutmelding wanneer u deze probeert uit te voeren.
  3. Wanneer u een Java-toepassing uitvoert met java , geeft u de klassenaam NIET de bytecode-bestandsnaam op.

Voorbeeld met pakketten

De meeste praktische Java-code maakt gebruik van pakketten om de naamruimte voor klassen te ordenen en het risico op botsing van klassennamen per ongeluk te verminderen.

Als we de klasse HelloWorld in een pakketoproep com.example , zou de "HelloWorld.java" de volgende Java-bron bevatten:

package com.example;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello world!");
    }
}

Dit broncodebestand moet worden opgeslagen in een mapstructuur waarvan de structuur overeenkomt met de naam van het pakket.

.    # the current directory (for this example)
|
 ----com
     |
      ----example
          |
           ----HelloWorld.java

We kunnen het bovenstaande bestand compileren met deze opdracht:

$ javac com/example/HelloWorld.java 

Dit produceert een bestand met de naam "com / example / HelloWorld.class"; dat wil zeggen na compilatie zou de bestandsstructuur er als volgt uit moeten zien:

.    # the current directory (for this example)
|
 ----com
     |
      ----example
          |
           ----HelloWorld.java
           ----HelloWorld.class

We kunnen de toepassing vervolgens als volgt uitvoeren:

$ java com.example.HelloWorld
Hello world!

Extra punten om op te merken uit dit voorbeeld zijn:

  1. De mapstructuur moet overeenkomen met de structuur van de pakketnaam.
  2. Wanneer u de klasse uitvoert, moet de volledige klassenaam worden opgegeven; dat wil zeggen "com.example.HelloWorld" niet "HelloWorld".
  3. U hoeft geen Java-code te compileren en uit te voeren vanuit de huidige map. We doen het hier alleen ter illustratie.

Meerdere bestanden tegelijk compileren met 'javac'.

Als uw toepassing uit meerdere broncodebestanden bestaat (en de meeste wel!), Kunt u ze één voor één compileren. Als alternatief kunt u meerdere bestanden tegelijkertijd compileren door de padnamen weer te geven:

$ javac Foo.java Bar.java

of gebruik de wildcard-functionaliteit van uw opdrachtshell ....

$ javac *.java
$ javac com/example/*.java
$ javac */**/*.java #Only works on Zsh or with globstar enabled on your shell

Dit compileert alle Java-bronbestanden in de huidige map, respectievelijk in de map "com / example" en recursief in onderliggende mappen. Een derde alternatief is het leveren van een lijst met bronbestandsnamen (en compileropties) als bestand. Bijvoorbeeld:

$ javac @sourcefiles

waar het sourcefiles bevat:

Foo.java
Bar.java
com/example/HelloWorld.java

Opmerking: het compileren van deze code is geschikt voor kleine eenmansprojecten en voor eenmalige programma's. Verder is het raadzaam om een Java-bouwtool te selecteren en te gebruiken. Als alternatief gebruiken de meeste programmeurs een Java IDE (bijv. NetBeans , eclipse , IntelliJ IDEA ) die een ingebedde compiler en incrementeel bouwen van "projecten" biedt.

Veelgebruikte 'javac'-opties

Hier zijn een paar opties voor de javac opdracht die waarschijnlijk nuttig voor u zijn

  • De optie -d stelt een doelmap in voor het schrijven van de ".class" -bestanden.
  • Met de optie -sourcepath wordt een zoekpad voor de broncode ingesteld.
  • De -cp of -classpath optie stelt het zoekpad voor het vinden van externe en eerder gecompileerde klassen. Raadpleeg het onderwerp Classpath voor meer informatie over het classpath en hoe u dit kunt opgeven.
  • De -version optie print versie informatie van de compiler.

Een meer complete lijst met compileropties zal in een afzonderlijk voorbeeld worden beschreven.

Referenties

De definitieve referentie voor de opdracht javac is de Oracle-hulppagina voor javac .

Compileren voor een andere versie van Java

De programmeertaal Java (en de runtime) heeft sinds de release ervan sinds de eerste publieke release veel veranderingen ondergaan. Deze wijzigingen omvatten:

  • Veranderingen in de syntaxis en semantiek van de programmeertaal Java
  • Wijzigingen in de API's verstrekt door de standaardbibliotheken van Java.
  • Wijzigingen in de Java-instructieset (bytecode) en de indeling van het klassenbestand.

Op enkele uitzonderingen na (bijvoorbeeld het enum trefwoord, wijzigingen in sommige "interne" klassen, enz.), Zijn deze wijzigingen achterwaarts compatibel.

  • Een Java-programma dat is gecompileerd met een oudere versie van de Java-toolchain, wordt zonder hercompilatie uitgevoerd op een nieuwere versie van het Java-platform.
  • Een Java-programma dat in een oudere versie van Java is geschreven, kan met succes worden gecompileerd met een nieuwe Java-compiler.

Oude Java compileren met een nieuwere compiler

Als u oudere Java-code op een nieuwer Java-platform (opnieuw) moet compileren om op het nieuwere platform te worden uitgevoerd, hoeft u over het algemeen geen speciale compilatievlaggen te geven. In enkele gevallen (bijvoorbeeld als u enum als identificatie had gebruikt), zou u de optie -source kunnen gebruiken om de nieuwe syntaxis uit te schakelen. Bijvoorbeeld, gegeven de volgende klasse:

public class OldSyntax {
    private static int enum;  // invalid in Java 5 or later
}

het volgende is vereist om de klasse te compileren met behulp van een Java 5-compiler (of later):

$ javac -source 1.4 OldSyntax.java

Compileren voor een ouder uitvoeringsplatform

Als u Java moet compileren om op oudere Java-platforms te draaien, is de eenvoudigste aanpak om een JDK te installeren voor de oudste versie die u moet ondersteunen en die JDK-compiler in uw builds te gebruiken.

Je kunt ook compileren met een nieuwere Java-compiler, maar die zijn ingewikkeld. Allereerst zijn er enkele belangrijke voorwaarden waaraan moet worden voldaan:

  • De code die u compileert, mag geen Java-taalconstructies gebruiken die niet beschikbaar waren in de versie van Java waarop u zich richt.
  • De code mag niet afhangen van standaard Java-klassen, velden, methoden en dergelijke die niet beschikbaar waren in de oudere platforms.
  • Bibliotheken van derden waarvan de code afhankelijk is, moeten ook voor het oudere platform worden gebouwd en beschikbaar zijn tijdens compilatie en runtime.

Als aan de voorwaarden is voldaan, kunt u code voor een ouder platform opnieuw compileren met de optie -target . Bijvoorbeeld,

$ javac -target 1.4 SomeClass.java

compileert de bovenstaande klasse om bytecodes te produceren die compatibel zijn met Java 1.4 of hoger JVM. (De optie -source impliceert in feite een compatibel -target , dus javac -source 1.4 ... zou hetzelfde effect hebben. De relatie tussen -source en -target wordt beschreven in de Oracle-documentatie.)

Dat gezegd hebbende, als je gewoon -target of -source , compileer je nog steeds met de standaardklassebibliotheken die door de JDK van de compiler worden geleverd. Als je niet oppast, kun je eindigen met klassen met de juiste bytecode-versie, maar met afhankelijkheden van API's die niet beschikbaar zijn. De oplossing is om de optie -bootclasspath gebruiken. Bijvoorbeeld:

$ javac -target 1.4 --bootclasspath path/to/java1.4/rt.jar SomeClass.java

compileert met een alternatieve set runtime-bibliotheken. Als de klasse die wordt gecompileerd (onbedoelde) afhankelijkheden heeft van nieuwere bibliotheken, levert dit compilatiefouten op.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow