Манипулируйте ссылку на объект 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 при создании экземпляра класса. Так что я официально в тупике.
Ответы
Ответ 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.