Mendapatkan versi Java saat runtime

128

Saya perlu mengatasi bug Java di JDK 1.5 yang diperbaiki di 1.6. Saya menggunakan kondisi berikut:

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

Apakah ini akan bekerja untuk JVM lain? Apakah ada cara yang lebih baik untuk memeriksa ini?

daftar
sumber

Jawaban:

41

Artikel-artikel ini tampaknya menyarankan bahwa memeriksa 1.5atau 1.6awalan harus bekerja, karena mengikuti konvensi penamaan versi yang tepat.

Artikel Teknis Sun

polygenelubricants
sumber
1
Apakah ada cara untuk mendapatkan apakah itu Oracle atau Open?
Joe C
89

java.versionadalah properti sistem yang ada di setiap JVM. Ada dua format yang memungkinkan untuk itu:

  • Java 8 atau lebih rendah: 1.6.0_23 , 1.7.0, 1.7.0_80,1.8.0_211
  • Java 9 atau lebih tinggi: 9.0.1,11.0.4 , 12,12.0.1

Berikut adalah trik untuk mengekstrak versi utama: Jika itu adalah 1.x.y_zstring versi, ekstrak karakter di indeks 2 dari string. Jika ax.y.z string versi, potong string ke karakter titik pertamanya, jika ada.

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);
}

Sekarang Anda dapat memeriksa versi jauh lebih nyaman:

if(getVersion() < 6) {
    // ...
}
Aaron Digulla
sumber
7
Tidak apa-apa untuk 1,5 tetapi 1,6 tidak tepat sebagai angka floating point.
Ha.
1
Di samping presisi FP, untuk kebutuhan OP, kode yang disediakan setidaknya harus (versi> 1.5), bukan> =. Ke OP: jika Anda menggunakan perbandingan String Anda saat ini, apakah Anda perlu memeriksa di bawah 1,5 juga?
Steven Mackenzie
1
@ Ha: Mungkin tapi double version = 1.6dan Double.parseDouble("1.6")masih harus menghasilkan pola bit yang sama, kan? Karena kami tidak melakukan aritmatika pada angka (hanya perbandingan sederhana), bahkan == akan berfungsi seperti yang diharapkan.
Aaron Digulla
1
tetapi segera kita akan memiliki versi 1.1 lagi ... atau mungkin bukannya 1.10 kita mulai dengan 2.0 [:-)
user85421
7
Di Jawa 9, tidak akan ada "1." di depan. Tali akan dimulai dengan "9 ..."
Dave C
59

Bagaimana dengan mendapatkan versi dari paket meta info:

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

Mencetak sesuatu seperti:

1.7.0_13

Stefan
sumber
9
Wow, hal itu mengejutkan saya. Meskipun dalam kasus saya, yang saya inginkan adalah dua bagian pertama dari versi ini jadi:Runtime.class.getPackage().getSpecificationVersion()
Wesley Hartford
8
Runtime.class.getPackage().getImplementationVersion()tampaknya kembali nullpada JDK9.
tresf
Mungkin ini hanya berfungsi ketika didefinisikan dalam MANIFEST.MF?
Aaron Digulla
30

Runtime.version()

Karena Java 9, Anda dapat menggunakan Runtime.version(), yang mengembalikan Runtime.Version:

Runtime.Version version = Runtime.version();
Eng.Fouad
sumber
echo "System.err.print (Runtime.version (). major ())" | $ JDK / bin / jshell 2> & 1> / dev / null
judovana
29

Cara paling sederhana ( java.specification.version ):

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

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

atau sesuatu seperti ( java.version ):

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

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

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

atau jika Anda ingin memecah semuanya ( 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];
mvanle
sumber
11

Catat saja bahwa di Java 9 dan di atasnya, konvensi penamaan berbeda. System.getProperty("java.version")mengembalikan "9"daripada "1.9".

Sina Madani
sumber
8

Tidak berfungsi, perlu --posmengevaluasi ganda:

    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;
}
Alessandro
sumber
7

Contoh untuk 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 :)
    }
mvanle
sumber
1
version < 1.4f... Apa yang terjadi kapan version = 1.4f?
ADTC
Ah ya, Anda benar - 1.4f tidak akan ditangkap dalam contoh di atas. Contohnya hanya menunjukkan konstanta Apache Commons Lang sebagai alternatif untuk properti Java :)
mvanle
Anda dapat mengedit jawabannya dan mengubahnya menjadi version <= 1.4f.. Sayangnya SystemUtilstidak menyediakan isJavaVersionLessThanmetode, tetapi kemudian (untungnya) Anda juga bisa memasukkan kode lama ke dalam elseblok, yang lebih bersih.
ADTC
Err ... "klausa cerdik untuk menangkap 1.4" ? Tidakkah seharusnya 1.4fkembali ke kode lama?
ADTC
2
Saya akan menyarankan: if (SystemUtils.IS_JAVA_1_5) { /* 1.5 specific code */ } else if (SystemUtils.isJavaVersionAtLeast(1.6f)) { /* modern code */ } else { /* fall back to legacy code */ }. Kode khusus di atas, kode umum di bawah, kode cadangan di bagian paling bawah.
ADTC
5

Inilah implementasinya di 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));
}
simon04
sumber
4

Jika Anda dapat memiliki ketergantungan pada utilitas apache, Anda dapat menggunakan org.apache.commons.lang3.SystemUtils.

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

Ini jawaban dari @mvanle, dikonversi ke Scala: scala> val Array(javaVerPrefix, javaVerMajor, javaVerMinor, _, _) = System.getProperty("java.runtime.version").split("\\.|_|-b") javaVerPrefix: String = 1 javaVerMajor: String = 8 javaVerMinor: String = 0

Mike Slinn
sumber