Можно ли написать оператор printf Java, который печатает сам оператор? - PullRequest
5 голосов
/ 22 мая 2010

Возможно ли иметь оператор Java printf, вывод которого - сам оператор?

Небольшой фрагмент для иллюстрации:

// attempt #1
public class Main {
public static void main(String[] args) {

System.out.printf("something");

}
}

Это печатает something.

Таким образом, результат попытки # 1 не совсем точно является оператором printf в попытке # 1. Мы можем попробовать что-то вроде этого:

// attempt #2
public class Main {
public static void main(String[] args) {

System.out.printf("System.out.printf(\"something\");");

}
}

А теперь вывод System.out.printf("something");

Итак, теперь результат попытки # 2 совпадает с оператором в выходе # 1, но мы вернулись к проблеме, с которой мы сталкивались ранее, поскольку нам нужен результат попытки # 2, чтобы соответствовать оператору в попытке # 2.

Так можно ли написать однострочное выражение printf, которое печатает само себя?

Ответы [ 2 ]

6 голосов
/ 22 мая 2010

Это не красиво, но это, безусловно, возможно:

public class Main {
public static void main(String[] args) {

System.out.printf("System.out.printf(%c%s%1$c,34,%1$c%2$s%1$c);",34,"System.out.printf(%c%s%1$c,34,%1$c%2$s%1$c);");

}
}

Выход ( при запуске на ideone.com ):

System.out.printf("System.out.printf(%c%s%1$c,34,%1$c%2$s%1$c);",34,"System.out.printf(%c%s%1$c,34,%1$c%2$s%1$c);");

Этовыходные данные совпадают с оператором printf.

Возможны более короткие решения.

См. также

2 голосов
/ 22 мая 2010

System.out - это статический экземпляр PrintStream, который может быть заменен любым PrintStream путем inovking System.out.setOut (PrintStream s). Итак, просто напишите подкласс PrintStream и переопределите необходимые методы. Ниже приведен очень простой пример для демонстрации. Желательно переопределить больше методов.

    public class VerbosePrintStream extends PrintStream{

        public VerbosePrintStream (PrintStream ps){
            super(ps, true);
        }

        @Override
        public void println(String x) {
            super.println("System.out.println(\""+x + "\");");
        }

    }

Теперь мы тестируем вышеуказанный класс:

VerbosePrintStream vps = new VerbosePrintStream(System.out);
    System.setOut(vps);
    System.out.println("test string");
...