Сравнение типов в Java
Источник:
Theflashreads
Благодаря этой публикации вы узнаете о нескольких вариантах сравнения типов в Java.
Самый распространенный способ определить, является ли данный объект
экземпляром данного класса, суперкласса или интерфейса, — это использовать бинарный оператор
instanceof. Он включает неявную проверку null и генерирует ошибку времени компиляции, если типы не связаны. При этом он не позволяет использовать примитивы и требует, чтобы типы были известны во время компиляции.
Если вам нужна динамическая проверка во время выполнения
В данном случае используйте эквивалентный метод
boolean isInstance(Object obj) в
Class. Он также включает нулевую проверку, но допускает примитивы:
a instanceof B
null instanceof B
a.getClass().isInstance(b);
Class<T> type = b.getClass();
type.isInstance(a);
int x = 4;
Integer.class.isInstance(x);
Проверка совместимости двух типов
Если вам нужно проверить отношение подтипа, используйте метод
boolean isAssignableFrom(Class<?> cls) в
Class. Это поможет выявить
NullPointerException.
Class<?> aClass = CharSequence.class;
Class<?> bClass = String.class;
bClass.isAssignableFrom(aClass());
CharSequence[].class.isAssignableFrom(String[].class);
Integer[].class.isAssignableFrom(String[].class);
Сопоставление с образцом (Java 14)
if(a instanceof B b) {
b.toString();
}
Специальные типы
enum Color { WHITE, GRAY, BLACK }
Color.class.isEnum();
Color.WHITE instanceof Enum;
String[].class.isArray();
Class<?> componentType = obj.getComponentType();
int.class.isPrimitive();
Java.io — Операции ввода-вывода в Java
Источник:
Medium
Содержание этой статьи посвящено операциям ввода-вывода в Java.
В Android-разработке и разработке Java-приложений ввод-вывод (Java I/O) — одна из тем, которая часто используется, но о которой почему-то редко упоминают. При этом сфера ее применения широка: например, мы выполняем операции ввода-вывода при преобразовании растрового изображения в формат JPEG или во время чтения/записи обычного файла.
В Java-пакете java.io есть все необходимые классы, необходимые для выполнения операций ввода-вывода. Эти операции выполняются с использованием потоков. В свою очередь, потоки помогают выполнять операции чтения или записи. Например, запись сообщения в файл.
Типы потоков
Существует два типа потоков в Java:
- Byte Stream (байтовый поток)
- Character Stream (поток символов)
Байтовый поток
Поток байтов (Byte Stream) используется для чтения и записи одного байта данных. Он включает классы Java
InputStream и
OutputStream.
InputStream помогает читать данные, а
OutputStream помогает записывать данные в цель (возможно, в файл).
Поток символов
Поток символов (Character Stream) используется для чтения и записи одного символа данных. Он включает в себя Java-классы
Reader и
Writer. Чтобы понять
Reader и
Writer, вы должны понимать производные классы, такие как
InputStreamReader,
FileReader,
OutputStreamWriter,
FileWriter и другие.
InputStream и OutputStream
InputStream используется для чтения данных из источника (возможно, из файла). Сам по себе он бесполезен, но у него есть несколько производных классов, таких как
FileInputStream,
ByteArrayInputStream и
ObjectInputStream.
OutputStream используется для записи данных в цель (возможно, в файл). Его производными классами являются
FileOutputStream,
ByteArrayOutputStream и
ObjectOutputStream.
class InputOutput {
data class Car(val name: String): java.io.Serializable
fun fileStream() {
val outputStream = FileOutputStream("kotlin.txt")
outputStream.write(1)
outputStream.write("hello".toByteArray())
val inputStream = FileInputStream("kotlin.txt")
println(inputStream.read())
val msg = String(inputStream.readBytes())
println(msg)
outputStream.close()
inputStream.close()
}
fun byteArrayStream() {
val outputStream = ByteArrayOutputStream()
outputStream.write(1)
outputStream.write("hello".toByteArray())
val readByteArray = outputStream.toByteArray()
val inputStream = ByteArrayInputStream(readByteArray)
println(inputStream.read())
val msg = String(inputStream.readBytes())
println(msg)
outputStream.close()
inputStream.close()
}
fun objectStream() {
val car = Car(name = "BMW")
val fileOutputStream = FileOutputStream("kotlin.txt")
val objOutputStream = ObjectOutputStream(fileOutputStream)
objOutputStream.writeObject(car)
val fileInputStream = FileInputStream("kotlin.txt")
val objInputStream = ObjectInputStream(fileInputStream)
val carObject = objInputStream.readObject() as Car
println(carObject.name)
fileOutputStream.close()
objOutputStream.close()
fileInputStream.close()
objInputStream.close()
}
fun bufferStream() {
val fileOutputStream = FileOutputStream("kotlin.txt")
val outputStream = BufferedOutputStream(fileOutputStream)
outputStream.write("hello".toByteArray())
outputStream.flush()
val fileInputStream = FileInputStream("kotlin.txt")
val inputStream = BufferedInputStream(fileInputStream)
val msg = String(inputStream.readBytes())
println(msg)
fileOutputStream.close()
fileInputStream.close()
}
}
Кроме вышеперечисленных потоков, у нас также есть
DataInputStream и
DataOutputStream. Они выполняют ту же работу, что и другие потоки. Различие заключается в том, что
DataInput/
OutputStream в основном используется для чтения/записи примитивных типов, а
ObjectInput/
OutputStream в основном используется для объектов и так далее.
Readers и Writers
В Java I/O, если мы читаем/записываем данные в потоки, мы должны сначала преобразовать их в байты. Только после этого мы можем читать или записывать их в потоки.
InputStreamReader и
OutputStreamWriter делают это автоматически.
class ReaderWriter {
fun readerWriter() {
val outputStream = FileOutputStream("kotlin.txt")
val writer = OutputStreamWriter(outputStream)
writer.write("Hello Kotlin")
writer.flush()
val inputStream = FileInputStream("kotlin.txt")
val reader = InputStreamReader(inputStream)
println(reader.readText())
}
}
Параллельное чтение и запись
Иногда нам нужна поддержка многопоточности в Streams. Проще говоря, мы хотим читать и записывать в streams из отдельных threads. Для этого нам нужно использовать
PipedInput/
OutputStream.
fun pipedStream() {
val inputStream = PipedInputStream()
val outputStream = PipedOutputStream()
inputStream.connect(outputStream)
val writeThread = object : Thread() {
override fun run() {
try {
for (i in 0..100) {
outputStream.write(i)
println("Write : $i")
sleep(100)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
val readThread = object : Thread() {
override fun run() {
try {
for (i in 0..100) {
println("Read : ${inputStream.read()}")
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
writeThread.start()
readThread.start()
}