• 0.00

  • 0.00

  • ,

com.javarush.task.task18.task1813

package com.javarush.task.task18.task1813;

import java.io.*;

/* 
AmigoOutputStream
*/

public class AmigoOutputStream extends FileOutputStream {
    public static String fileName = "D:/tmp/result.txt";
    private FileOutputStream original = null;


    public AmigoOutputStream(FileOutputStream fileOutputStream) throws Exception {
        super(fileOutputStream.getFD());
        this.original = fileOutputStream;
    }

    @Override
    public void write(int b) throws IOException {
        original.write(b);
    }

    @Override
    public void write(byte[] b) throws IOException {
        original.write(b);
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        original.write(b, off, len);
    }

    @Override
    public void close() throws IOException {
        original.flush();
        original.write("JavaRush © All rights reserved.".getBytes());
        original.close();
    }

    @Override
    public void flush() throws IOException {
        original.flush();
    }

    public static void main(String[] args) throws Exception {
        new AmigoOutputStream(new FileOutputStream(fileName));
    }

}

Вот такое решение получилось. После того как валидатор принял его, решил протестировать.
переписал метод main следующим образом:
AmigoOutputStream amigoOutputStream = new AmigoOutputStream(new FileOutputStream(fileName));
        amigoOutputStream.close();

Открываю выходной файл и вижу там:
JavaRush © All rights reserved.JavaRush © All rights reserved.

Строка записалась два (!) раза. Отладка показала что переопределенный метод close выполняется два раза…

До верного решения додумался сам заменив строку :
super(fileOutputStream.getFD());
на :
super(filename);
но у меня остались вопросы:
Что это за FileDescriptor, который возвращает метод getFD()?
Получается с его помощью нельзя инициализировать FileOutputStream?
И почему при таком вызове конструктора суперкласса метод close выполняется два раза?
  • ,

Получение доступа к private полям??

Я заметил это решая задачу Stopwatch (Секундомер).
Обратите внимание на метод doStep класса Stopwatch.

package com.javarush.task.task16.task1612;

public class Solution {
    public static volatile boolean isStopped = false;

    public static void main(String[] args) throws InterruptedException {
        Runner ivanov = new Runner("Ivanov", 4);
        Runner petrov = new Runner("Petrov", 2);
        ivanov.start();
        petrov.start();
        Thread.sleep(2000);
        isStopped = true;
        Thread.sleep(1000);
    }

    public static class Stopwatch extends Thread {
        private Runner owner;
        private int stepNumber;

        public Stopwatch(Runner runner) {
            this.owner = runner;
        }

        public void run() {
            try {
                while (!isStopped) {
                    doStep();
                }
            } catch (InterruptedException e) {
            }
        }

        private void doStep() throws InterruptedException {
            stepNumber++;
            Thread.sleep((long)1000 / owner.speed);
            System.out.println(owner.getName() + " делает шаг №" + stepNumber + "!");
        }
    }

    public static class Runner {
        Stopwatch stopwatch;
        private String name;
        private int speed;

        public Runner(String name, int speed) {
            this.name = name;
            this.speed = speed;
            this.stopwatch = new Stopwatch(this);
        }

        public String getName() {
            return name;
        }

        public int getSpeed() {
            return speed;
        }

        public void start() {
            stopwatch.start();
        }
    }
}


А точнее на строку
Thread.sleep((long)1000 / owner.speed);

Этот код компилируется и запускается.
Как это работает?? Почему?? ведь поле speed класса Runner объявлено:
private int speed;

Получается что можно получить доступ к private полям объекта?
Умные люди! Объясните пожалуйста или тыкните носом если ответ очевиден.