Кофе-брейк #169. Сравнение типов. Java.io — Операции ввода-вывода в Java

Статья из группы Random

Сравнение типов в Java

Источник: Theflashreads Благодаря этой публикации вы узнаете о нескольких вариантах сравнения типов в Java. Кофе-брейк #169. Сравнение типов. Java.io — Операции ввода-вывода в Java - 1Самый распространенный способ определить, является ли данный объект экземпляром данного класса, суперкласса или интерфейса, — это использовать бинарный оператор instanceof. Он включает неявную проверку null и генерирует ошибку времени компиляции, если типы не связаны. При этом он не позволяет использовать примитивы и требует, чтобы типы были известны во время компиляции.

Если вам нужна динамическая проверка во время выполнения

В данном случае используйте эквивалентный метод boolean isInstance(Object obj) в Class. Он также включает нулевую проверку, но допускает примитивы:

a instanceof B 
    // returns false for null
    null instanceof B

    a.getClass().isInstance(b);
    // commonly used for generics
    Class<T> type = b.getClass();
    type.isInstance(a);

    // Note that the parameter is autoboxed to type Integer
    int x = 4;
    Integer.class.isInstance(x);

Проверка совместимости двух типов

Если вам нужно проверить отношение подтипа, используйте метод boolean isAssignableFrom(Class<?> cls) в Class. Это поможет выявить NullPointerException.

 // is it possible to B b = new A()
    Class<?> aClass = CharSequence.class;
    Class<?> bClass = String.class;
    bClass.isAssignableFrom(aClass());

    // works for arrays
    CharSequence[].class.isAssignableFrom(String[].class); // true
    Integer[].class.isAssignableFrom(String[].class); //false

Сопоставление с образцом (Java 14)


 if(a instanceof B b) {
        // b is casted
        b.toString();
    }

Специальные типы


// Enums
    enum Color { WHITE, GRAY, BLACK }

    Color.class.isEnum(); // Enum.class.isAssignableFrom(Color.class); 
    Color.WHITE instanceof Enum; // true

    // Arrays
    String[].class.isArray();
    // get the type of the variables in an array (null if obj is not an array)
    Class<?> componentType = obj.getComponentType(); 

    // Primitives
    int.class.isPrimitive();

Java.io — Операции ввода-вывода в Java

Источник: Medium Содержание этой статьи посвящено операциям ввода-вывода в Java. Кофе-брейк #169. Сравнение типов. Java.io — Операции ввода-вывода в Java - 2В Android-разработке и разработке Java-приложений ввод-вывод (Java I/O) — одна из тем, которая часто используется, но о которой почему-то редко упоминают. При этом сфера ее применения широка: например, мы выполняем операции ввода-вывода при преобразовании растрового изображения в формат JPEG или во время чтения/записи обычного файла. В Java-пакете java.io есть все необходимые классы, необходимые для выполнения операций ввода-вывода. Эти операции выполняются с использованием потоков. В свою очередь, потоки помогают выполнять операции чтения или записи. Например, запись сообщения в файл.

Типы потоков

Существует два типа потоков в Java:
  1. Byte Stream (байтовый поток)
  2. 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() {
        //Create FileOutputStream that used for writing to file
        val outputStream = FileOutputStream("kotlin.txt")

        //write to output stream
        outputStream.write(1) //write a int
        outputStream.write("hello".toByteArray()) //write a string as byte array

        //Create FileInputStream that used for reading from file
        val inputStream = FileInputStream("kotlin.txt")

        //reading single first byte from input stream
        //output - 1
        println(inputStream.read())

        //reading string from input stream
        //output - hello
        val msg = String(inputStream.readBytes())
        println(msg)

        //close
        outputStream.close()
        inputStream.close()
    }

    fun byteArrayStream() {
        //Create ByteArrayOutputStream
        val outputStream = ByteArrayOutputStream()

        //write to output stream
        outputStream.write(1)
        outputStream.write("hello".toByteArray())

        //Create ByteArrayInputStream
        val readByteArray = outputStream.toByteArray()
        val inputStream = ByteArrayInputStream(readByteArray)

        //Reading a single byte from input stream
        //output - 1
        println(inputStream.read())

        //Reading string from input stream
        //output - hello
        val msg = String(inputStream.readBytes())
        println(msg)

        //close
        outputStream.close()
        inputStream.close()
    }

    fun objectStream() {
        //custom object
        val car = Car(name = "BMW")

        //Create ObjectOutputStream
        val fileOutputStream = FileOutputStream("kotlin.txt")
        val objOutputStream = ObjectOutputStream(fileOutputStream)

        //writing to output stream
        objOutputStream.writeObject(car)

        //Create ObjectInputStream
        val fileInputStream = FileInputStream("kotlin.txt")
        val objInputStream = ObjectInputStream(fileInputStream)

        //Reading from input stream
        val carObject = objInputStream.readObject() as Car
        println(carObject.name) //output - BMW

        //close
        fileOutputStream.close()
        objOutputStream.close()

        fileInputStream.close()
        objInputStream.close()
    }

    fun bufferStream() {
        //Buffer - Buffer is used for storing stream of data in Java I/O
        //BufferStream is faster way to write and read bytes in streams.

        //Create BufferOutputStream
        val fileOutputStream = FileOutputStream("kotlin.txt")
        val outputStream = BufferedOutputStream(fileOutputStream)

        //Write to output stream
        outputStream.write("hello".toByteArray())

        //flush() - Sending the data from BufferedOutputStream to main stream.
        //This is required to push changes to main stream.
        outputStream.flush()

        //Create BufferInputStream
        val fileInputStream = FileInputStream("kotlin.txt")
        val inputStream = BufferedInputStream(fileInputStream)

        //Reading from input stream
        val msg = String(inputStream.readBytes())
        println(msg)

        //close
        fileOutputStream.close()
        fileInputStream.close()
    }
}
Кроме вышеперечисленных потоков, у нас также есть DataInputStream и DataOutputStream. Они выполняют ту же работу, что и другие потоки. Различие заключается в том, что DataInput/OutputStream в основном используется для чтения/записи примитивных типов, а ObjectInput/OutputStream в основном используется для объектов и так далее.

Readers и Writers

В Java I/O, если мы читаем/записываем данные в потоки, мы должны сначала преобразовать их в байты. Только после этого мы можем читать или записывать их в потоки. InputStreamReader и OutputStreamWriter делают это автоматически.

class ReaderWriter {
    fun readerWriter() {
        //StreamReader or Writer:
        //It reads bytes and decodes them into characters using a specified charset.

        //Create OutputStreamWriter
        val outputStream = FileOutputStream("kotlin.txt")
        val writer = OutputStreamWriter(outputStream)

        //write to output stream
        writer.write("Hello Kotlin")
        writer.flush()

        //Create InputStreamReader
        val inputStream = FileInputStream("kotlin.txt")
        val reader = InputStreamReader(inputStream)

        //read from input stream
        //output - Hello Kotlin
        println(reader.readText())
    }
}

Параллельное чтение и запись

Иногда нам нужна поддержка многопоточности в Streams. Проще говоря, мы хотим читать и записывать в streams из отдельных threads. Для этого нам нужно использовать PipedInput/OutputStream.

 fun pipedStream() {
        //Create PipedInput/OutputStream for parallel read/writes
        val inputStream = PipedInputStream()
        val outputStream = PipedOutputStream()

        //make a connection
        inputStream.connect(outputStream)

        //write from separate thread
        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()
                }
            }
        }

        //read from another thread
        val readThread = object : Thread() {
            override fun run() {
                try {
                    for (i in 0..100) {
                        println("Read : ${inputStream.read()}")
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }

        //start
        writeThread.start()
        readThread.start()
    }
Комментарии (1)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Родион Корнеев Уровень 3
13 ноября 2022
В разделе Проверка совместимости двух типов в 4 строчке кода примера не нужны скобки после имени переменной `aClass`

bClass.isAssignableFrom(aClass()); // <- тут