ObjectInputStream - чтение объекта - Есть ли способ предотвратить вызов конструктора суперкласса no arg? - PullRequest
0 голосов
/ 23 января 2019

Я записываю объект PreferedCustomer в файл .dat, используя FileIOStreams и ObjectIOStreams. Я практикую Наследование, поэтому существует простая иерархия классов.

PreferredCustomer.java наследуется от Customer.java

Customer.java наследуется от Person.java.

Когда я считываю свой объект PreferredCustomer из файла .dat, он вызывает конструктор no arg Person.java и устанавливает для полей «Имя», «Адрес» и «PhoneNumber» значение «». Как я могу предотвратить вызов конструкции no arg, которая сбрасывает значения String?

У меня есть проект, размещенный на github. https://github.com/davidmistretta/CustomerObjectDAT

Код, который, я считаю, должен быть переработан, находится в Consumers -> src -> CustomerDemo -> StoreConsumerObjects.java, строки 30-> 40 (инструкция try / catch ниже)

Основной метод, который записывает объект, затем читает объект

public static void main(String[] args)
{
    try (FileOutputStream fos = new FileOutputStream("customers.dat");
         ObjectOutputStream oos = new ObjectOutputStream(fos)) {

        PreferredCustomer pc = new PreferredCustomer("David Mistretta","943 Fakedale Way, Funnyvale, MO, 01337","978-000-0000","01A001");
        pc.setBalance(550);
        System.out.println("Object to input into customers.dat\n" + pc.toString() +"\n\n");
        oos.writeObject(pc);
    } catch (IOException e) {
        e.printStackTrace();
    }

    try (FileInputStream fis = new FileInputStream("customers.dat");
         ObjectInputStream ois = new ObjectInputStream(fis)) {

        PreferredCustomer pca = (PreferredCustomer) ois.readObject();
        System.out.println("Object output from customers.dat\n" + pca.toString());
        ois.close();
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    } 
} 

Конструктор без аргументов, который я написал в Person.java (строки 28 -> 34)

public Person() 
{
    System.out.println("Person no arg construct");
    m_name = "";
    m_phoneNumber = "";
    m_address = "";
}

токовый выход

Object to input into customers.dat
Preferred Customer
Name: David Mistretta
Address: 943 Fakedale Way, Funnyvale, MO, 01337
Phone Number: 978-000-0000
Customer Number: 01A001
Mailing List: true
Balance: 550.0
Discount: 0.05


Person no arg construct
Object output from customers.dat
Preferred Customer
Name: 
Address: 
Phone Number: 
Customer Number: 01A001
Mailing List: true
Balance: 550.0
Discount: 0.05

Я ожидаю, что поля Имя, Адрес и Номер телефона будут отражать поля, когда они были введены. Я следовал инструкциям о том, как сохранить объект в файле здесь https://kodejava.org/how-do-i-store-objects-in-file/

Если бы кто-то мог указать мне правильное направление, как с этим справиться, это было бы оценено.

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Итак, я забыл добавить Serializable в своем классе Person.java. Спасибо Тому Хоутину (Tom Hawtin) за то, что он сказал мне, что конструктор суперкласса вызывается раньше всего на классах Serializable, что приводит меня к источнику моей проблемы. Таким образом, чтобы предотвратить вызов аргумента no arg в конструктор суперкласса при чтении объектов из ObjectInputStream, убедитесь, что суперкласс использует интерфейс Serializable. Если это не так, конструктор no arg будет вызван.

0 голосов
/ 23 января 2019

Каждый не Serializable конструктор класса должен быть вызван. Язык Java запрещает все остальное. Механизм Сериализации Java должен уклониться от проверки байт-кода, чтобы избежать конструктора. В некоторых классах конструкторы могут выполнять какую-то проверку безопасности.

Однако конструктор суперкласса вызывается раньше всего в классах Serializable. Таким образом, ваша проблема, вероятно, в другом месте.

(Примечание: уничтожение и воссоздание людей с целью изменения их предпочтительного статуса осуждается.)

...