Подтвердить что ты не робот

Манипулируйте ссылку на объект Java с помощью конструктора классов

Это вопрос экзамена, который я не мог выполнить.

Как получить следующий java-код для печати false только редактирование кода в конструкторе MyClass?

public class MyClass{        
    public MyClass(){
    }

    public static void main(String[] args) {            
        MyClass m = new MyClass();
        System.out.println(m.equals(m));
    }
}

Вам не разрешается переопределять метод equals или изменять любой из код в основном методе. Код должен работать без программы сбой.

Согласно моему исследованию, вы не можете установить ссылку на объект Java равным null при создании экземпляра класса. Так что я официально в тупике.

4b9b3361

Ответ 1

Это было сложно!

public MyClass() {
    System.setOut(new PrintStream(new FilterOutputStream(System.out) {
        @Override
        public void write(byte[] b, int off, int len) throws IOException {
            if(new String(b).contains("true")) {
                byte[] text = "false".getBytes();         
                super.write(text, 0, text.length);
            }
            else {
                super.write(b, off, len);
            }
        }
    }, true));
}

Или Пол Боддингтон упрощенная версия:

PrintStream p = System.out; 
System.setOut(new PrintStream(p) { 
    @Override
    public void println(boolean b) { 
        p.println(false); 
    }
});

Ответ 2

Что-то в этом направлении, я бы предположил:

public MyClass() {
    System.out.println(false);
    System.exit(0);
}

РЕДАКТИРОВАТЬ: Я нашел головоломку, очень похожую на твою в Java Puzzlers, за исключением этого вопроса единственное ограничение заключается в том, что вы не можете переопределить equals, что в основном заставляет решение перегрузить его и просто вернуть false. Кстати, мое решение выше было также дано как альтернативный ответ на эту загадку.

Ответ 3

Другим решением является

public MyClass() {
    new PrintStream(new ByteArrayOutputStream()).println(true);
    try {
        Field f = String.class.getDeclaredField("value");
        f.setAccessible(true);
        f.set("true", f.get("false"));
    } catch (Exception e) {
    }
}

Первая строка необходима, потому что необходимо, чтобы строковый литерал "true" встречался в классе PrintStream до изменения массива подстановки. См. этот вопрос.

Ответ 4

Это мое решение

public class MyClass {

    public MyClass() {
        System.out.println("false");

        // New class
        class NewPrintStream extends PrintStream {
            public NewPrintStream(OutputStream out) {
                super(out);
            }

            @Override
            public void println(boolean b) {
                // Do nothing
            }
        }

        NewPrintStream nps = new NewPrintStream(System.out);
        System.setOut(nps);
    }

    public static void main(String[] args) {
        MyClass m = new MyClass();
        System.out.println(m.equals(m));
    }
}

В принципе, это вариация решения @fikes.