Ottenere la versione Java in fase di esecuzione


128

Ho bisogno di aggirare un bug Java in JDK 1.5 che è stato corretto in 1.6. Sto usando la seguente condizione:

if (System.getProperty("java.version").startsWith("1.5.")) {
    ...
} else {
    ...
}

Funzionerà con altre JVM? C'è un modo migliore per controllare questo?

Risposte:


41

Questi articoli sembrano suggerire che il controllo 1.5o il 1.6prefisso dovrebbero funzionare, poiché segue la convenzione di denominazione della versione corretta.

Articoli tecnici Sun


1
C'è un modo per ottenere se è Oracle o Open?
Joe C

89

java.versionè una proprietà di sistema che esiste in ogni JVM. Ci sono due possibili formati per questo:

  • Java 8 o abbassare: 1.6.0_23, 1.7.0, 1.7.0_80,1.8.0_211
  • Java 9 o superiore: 9.0.1, 11.0.4, 12,12.0.1

Ecco un trucco per estrarre la versione principale: Se si tratta di una 1.x.y_zstringa di versione, estrarre il carattere nell'indice 2 della stringa. Se è una x.y.zstringa di versione, taglia la stringa al suo primo carattere punto, se esiste.

private static int getVersion() {
    String version = System.getProperty("java.version");
    if(version.startsWith("1.")) {
        version = version.substring(2, 3);
    } else {
        int dot = version.indexOf(".");
        if(dot != -1) { version = version.substring(0, dot); }
    } return Integer.parseInt(version);
}

Ora puoi controllare la versione molto più comodamente:

if(getVersion() < 6) {
    // ...
}

7
Va bene per 1.5 ma 1.6 non è preciso come un numero in virgola mobile.
Ah

1
Precisione FP a parte, per le esigenze del PO il codice fornito dovrebbe essere almeno (versione> 1.5), non> =. All'OP: se usi il tuo attuale confronto di stringhe devi controllare anche sotto 1.5?
Steven Mackenzie,

1
@Ha: Forse ma double version = 1.6e Double.parseDouble("1.6")dovrebbe comunque produrre lo stesso schema di bit, giusto? Dal momento che non facciamo aritmetiche sul numero (solo un semplice confronto), anche == funzionerà come previsto.
Aaron Digulla,

1
ma presto avremo di nuovo la versione 1.1 ... o forse invece dell'1.10 iniziamo con 2.0 [:-)
user85421

7
In Java 9, non ci sarà "1." di fronte. La stringa inizierà con "9 ..."
Dave C

59

Che ne dici di ottenere la versione dalle meta informazioni del pacchetto:

String version = Runtime.class.getPackage().getImplementationVersion();

Stampa qualcosa del tipo:

1.7.0_13


9
Wow, quel tipo di mi ha fatto impazzire. Anche se nel mio caso, tutto ciò che volevo erano le prime due parti della versione, quindi:Runtime.class.getPackage().getSpecificationVersion()
Wesley Hartford,

8
Runtime.class.getPackage().getImplementationVersion()sembra tornare nullsu JDK9.
tresf,

Forse questo funziona solo quando è definito in MANIFEST.MF?
Aaron Digulla,


29

Il modo più semplice ( java.specification.version ):

double version = Double.parseDouble(System.getProperty("java.specification.version"));

if (version == 1.5) {
    // 1.5 specific code
} else {
    // ...
}

o qualcosa del genere ( java.version ):

String[] javaVersionElements = System.getProperty("java.version").split("\\.");

int major = Integer.parseInt(javaVersionElements[1]);

if (major == 5) {
    // 1.5 specific code
} else {
    // ...
}

o se vuoi rompere tutto ( java.runtime.version ):

String discard, major, minor, update, build;

String[] javaVersionElements = System.getProperty("java.runtime.version").split("\\.|_|-b");

discard = javaVersionElements[0];
major   = javaVersionElements[1];
minor   = javaVersionElements[2];
update  = javaVersionElements[3];
build   = javaVersionElements[4];

11

Solo una nota che in Java 9 e versioni successive, la convenzione di denominazione è diversa. System.getProperty("java.version")ritorna "9"piuttosto che "1.9".


8

Non funziona, è necessario --posvalutare il doppio:

    String version = System.getProperty("java.version");
    System.out.println("version:" + version);
    int pos = 0, count = 0;
    for (; pos < version.length() && count < 2; pos++) {
        if (version.charAt(pos) == '.') {
            count++;
        }
    }

    --pos; //EVALUATE double

    double dversion = Double.parseDouble(version.substring(0, pos));
    System.out.println("dversion:" + dversion);
    return dversion;
}

7

Esempio per Apache Commons Lang:

import org.apache.commons.lang.SystemUtils;

    Float version = SystemUtils.JAVA_VERSION_FLOAT;

    if (version < 1.4f) { 
        // legacy
    } else if (SystemUtils.IS_JAVA_1_5) {
        // 1.5 specific code
    } else if (SystemUtils.isJavaVersionAtLeast(1.6f)) {
        // 1.6 compatible code
    } else {
        // dodgy clause to catch 1.4 :)
    }

1
version < 1.4f... Cosa succede quando version = 1.4f?
ADTC,

Ah sì, hai ragione - 1.4f non verrebbe catturato nell'esempio sopra. L'esempio dimostra solo le costanti di Apache Commons Lang in alternativa alle proprietà di Java :)
mvanle,

Puoi modificare la risposta e cambiarla in version <= 1.4f.. Purtroppo SystemUtilsnon fornisce un isJavaVersionLessThanmetodo ma poi (fortunatamente) potresti anche mettere il codice legacy in un elseblocco, che è più pulito.
ADTC

Err ... "clausola ingannevole per catturare 1.4" ? Non dovresti 1.4ftornare al codice legacy?
ADTC

2
Vorrei suggerire: if (SystemUtils.IS_JAVA_1_5) { /* 1.5 specific code */ } else if (SystemUtils.isJavaVersionAtLeast(1.6f)) { /* modern code */ } else { /* fall back to legacy code */ }. Codice specifico sopra, codice generico sotto, codice di fallback in fondo.
ADTC

5

Ecco l'implementazione in JOSM :

/**
 * Returns the Java version as an int value.
 * @return the Java version as an int value (8, 9, etc.)
 * @since 12130
 */
public static int getJavaVersion() {
    String version = System.getProperty("java.version");
    if (version.startsWith("1.")) {
        version = version.substring(2);
    }
    // Allow these formats:
    // 1.8.0_72-ea
    // 9-ea
    // 9
    // 9.0.1
    int dotPos = version.indexOf('.');
    int dashPos = version.indexOf('-');
    return Integer.parseInt(version.substring(0,
            dotPos > -1 ? dotPos : dashPos > -1 ? dashPos : 1));
}

4

Se puoi avere dipendenza da apache utils puoi usare org.apache.commons.lang3.SystemUtils.

    System.out.println("Is Java version at least 1.8: " + SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_8));


1

Ecco la risposta di @mvanle, convertita in Scala: scala> val Array(javaVerPrefix, javaVerMajor, javaVerMinor, _, _) = System.getProperty("java.runtime.version").split("\\.|_|-b") javaVerPrefix: String = 1 javaVerMajor: String = 8 javaVerMinor: String = 0

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.