Получение версии Java во время выполнения

Мне нужно обойти ошибку Java в JDK 1.5, которая была исправлена ​​в 1.6. Я использую следующее условие:

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

Будет ли это работать для других JVM? Есть ли лучший способ проверить это?

14 ответов

Решение

Эти статьи, кажется, предполагают, что проверка на 1.5 или же 1.6 Префикс должен работать, так как он соответствует правилам именования версий.

Sun Технические статьи

java.version это стандартное свойство, которое существует в каждой виртуальной машине.

Есть только маленькая хитрость, которая может облегчить вашу жизнь: найдите вторую точку и обрежьте там строку. Затем преобразовать его в double, Теперь вы можете проверить версию гораздо удобнее:

if (version >= 1.5) ...

Вы можете поместить это в статический код класса, чтобы он выполнялся только один раз:

public static double JAVA_VERSION = getVersion ();

static double getVersion () {
    String version = System.getProperty("java.version");
    int pos = version.indexOf('.');
    pos = version.indexOf('.', pos+1);
    return Double.parseDouble (version.substring (0, pos));
}

Начиная с Java 9, вы можете использовать Runtime.version():

Runtime.Version version = Runtime.version();

Как насчет получения версии из метаинформации пакета:

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

Распечатывает что-то вроде:

1.7.0_13

Самый простой способ (java.specification.version):

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

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

или что-то вроде (java.version):

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

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

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

или если вы хотите разбить все это (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];

Пример для 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 :)
    }

Просто обратите внимание, что в Java 9 и выше соглашение об именах отличается. System.getProperty("java.version") возвращается "9" скорее, чем "1.9",

Не работает, нужно --pos оценить дважды:

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

Вот реализация в 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));
}

Если вы можете зависеть от утилит apache, вы можете использовать org.apache.commons.lang3.SystemUtils.

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

Не знаю другого способа проверить это, но это: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/System.html "подразумевает"java.version"является стандартным системным свойством, поэтому я ожидаю, что оно будет работать с другими JVM.

Вот ответ от @mvanle, преобразованный в Scala: scala> val Array(javaVerPrefix, javaVerMajor, javaVerMinor, _, _) = System.getProperty("java.runtime.version").split("\\.|_|-b") javaVerPrefix: String = 1 javaVerMajor: String = 8 javaVerMinor: String = 0

https://docs.oracle.com/javase/9/docs/api/java/lang/Runtime.Version.html#version--

       Runtime.version().version()

Для 17.0.1 он возвращает [17, 0, 1]. Можно использоватьRuntime.version().version().get(0)чтобы получить основную версию Java.

В котлине:

      /**
 * Returns the major JVM version, e.g. 6 for Java 1.6, 8 for Java 8, 11 for Java 11 etc.
 */
public val jvmVersion: Int get() = System.getProperty("java.version").parseJvmVersion()

/**
 * Returns the major JVM version, 1 for 1.1, 2 for 1.2, 3 for 1.3, 4 for 1.4, 5
 * for 1.5 etc.
 */
fun String.parseJvmVersion(): Int {
    val version: String = removePrefix("1.").takeWhile { it.isDigit() }
    return version.toInt()
}
Другие вопросы по тегам