Почему Socket не является экземпляром Closeable во время выполнения?
В приложении для Android я добавил этот код в onCreate()
Closeable sss = new Socket();
if (!(sss instanceof Closeable)) {
throw new RuntimeException("Something unexpected happened");
}
Импорт:
import java.io.Closeable;
import java.net.Socket;
Код компилируется, но я получаю исключение:
E/AndroidRuntime( 8293): java.lang.RuntimeException: Unable to start activity...: java.lang.RuntimeException: Something unexpected happened
...
E/AndroidRuntime( 8293): Caused by: java.lang.RuntimeException: Something unexpected happened
...
В другом контексте глюк вызывает java.lang.ArrayStoreException
(а именно, java.lang.ArrayStoreException: java.net.Socket не может быть сохранен в массиве типа java.io.Closeable []).
Я что-то пропустил? Есть идеи, что делать?
РЕДАКТИРОВАТЬ Точно так же, когда DatagramSocket
используется как MyClass<DatagramSocket>
за MyClass<T extends Closeable>
, это вызывает java.lang.IncompatibleClassChangeError: интерфейс не реализован.
3 ответа
Эта проблема возникает на уровнях API Android до 19. В уязвимых версиях Socket не реализует Closeable.
Источники:
Сокет сам по себе не является закрываемым, но оба его потока являются. И закрытие любого потока закроет сокет
Для будущих читателей я хочу уточнить кое-что, что, как предполагалось, было очевидно всем в этой дискуссии:
Как я мог назначить Closeable sss = new Socket();
если Socket
не является Closeable
?
Требования API, указанные в AndroidManifest.xml:
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
и устройство сообщает
android.os.Build.VERSION.SDK_INT=16
Код был скомпилирован для уровня API19, поэтому был успешно скомпилирован. Но он был запущен на уровне API16, и именно поэтому он потерпел неудачу.
Другими словами, проверка времени компиляции была выполнена для API19 на одном компьютере (настольном ПК), в то время как проверка времени выполнения была выполнена для API16 на другом компьютере (портативное устройство).