После поиска и проверки путем переключения установленного JDK между 8 и 11 я обнаружил, что есть некоторые изменения (new overridden methods)
, примененные к нескольким методам (например, flip (), clear () ) в классе ByteBuffer.
В Java 8 при вызове метода filp()
класса ByteBuffer, поскольку у него нет реализации для этого метода, поэтому он фактически вызывает метод из расширенного класса, Buffer; который возвращает Buffer
объект, как показано ниже:
В Буфер класс:
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
Однако в Java 11 класс ByteBuffer реализовал свой собственный флип (), и возвращаемый объект изменяется с Buffer на ByteBuffer (это изменение следует начинать с Java 9):
In ByteBuffer класс:
ByteBuffer flip() {
super.flip();
return this;
}
Поскольку я использую JDK 11 (более поздняя версия JDK) для компиляции программы для запуска на Java 8, упомянутое исключение иногда встречалось бы в соответствии с javado c:
По умолчанию, однако, javac компилируется с самой последней версией API платформы. Поэтому скомпилированная программа может случайно использовать API-интерфейсы, доступные только в текущей версии платформы. Такие программы не могут работать на более старых версиях платформы, независимо от значений, переданных опциям -source и -target. Это долговременная проблема удобства использования, так как пользователи ожидают, что с помощью этих опций они получат файлы классов, которые могут работать на версии платформы, указанной в -target.
Оператор может быть здесь указано: http://openjdk.java.net/jeps/247
Итак, для решения такого рода проблем есть 2 способа сделать это:
Подход 1
Можно обрабатывать во время компиляции, используя недавно введенный параметр командной строки:
i.e.
javac --release N <source files>
which is equals to:
for N < 9: -source N -target N -bootclasspath <documented-APIs-from-N>,
for N >= 9: -source N -target N --system <documented-APIs-from-N>.
Подход 2
Или мы можем обработать его в кодах в качестве методов предосторожности, явно приведя ByteByffer к типу Buffer перед вызовом соответствующих методов:
((Buffer) bb) .flip ();
, чтобы заставить его вызывать метод расширенного класса (в случае, если процесс компиляции не учел новые параметры командной строки):
private String loadFromFile(){
RandomAccessFile inFile = null;
FileChannel inChannel = null;
StringBuilder sb = new StringBuilder();
try {
inFile = new RandomAccessFile(this.latestImageFile, "r");
inChannel = inFile.getChannel();
ByteBuffer bb = ByteBuffer.allocate(2046);
while( inChannel.read(bb) != -1){
((Buffer)bb).flip(); // explicitly casting
while(bb.hasRemaining()){
char c = (char) bb.get();
sb.append(c);
}
((Buffer) bb).clear(); // explicitly casting
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inChannel != null) try {inChannel.close(); } catch (IOException e){}
if (inFile != null ) try { inFile.close(); } catch (IOException e) {}
}
return sb.toString();
}