7

最近の面接で聞かれた問題で立ち往生しています。問題は次のように述べられていました。

Jdk API の System クラスにアクセスできないとします。ECHO も使用できません。JRE 5 環境にいます。コンソールに何かをどのように出力しますか?

質問は実際には次のようなものから始まりました - なぜ Java は私たちにPrintStreamオブジェクトを与えたのSystem.outですか? そして、なぜそれは最終的なのですか?コンソールに何かを印刷する他の方法はありませんか?

4

6 に答える 6

16

必要に応じて System object をバイパスできます。System.out は多くの余分な処理 (たとえば、Unicode の処理) を行うため、生の出力とパフォーマンスだけが本当に必要な場合は、おそらくそれをバイパスする必要があります。

import java.io.*;

public class PrintOutTest {
  public static void main(String args[]) throws IOException {
    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new
      FileOutputStream(FileDescriptor.out), "ASCII"), 512);
    out.write("test string");
    out.write('\n');
    out.flush();
  }
}

これについては、こちらでさらに詳しく説明しています。

于 2012-11-01T07:43:41.577 に答える
4

PrintStream は、Windows コンソールで/できる/できるすべてのことを行うため、最終的なものです。また、「Console」が C# の const クラスであることも同じです。クラスは、コンソールが実行できるすべてをカプセル化し、特定の 1 つの方法でのみ実行します。ある時点で、それを処理するのはOS次第であるため、「改善」することはできません。

画面に何かを出力する方法はたくさんあります。

  1. @eis が行った方法で独自の OutputStream を記述します
  2. JNI を使用して、次のようなネイティブ関数を呼び出すネイティブ DLL/SO でメソッドを呼び出します。printf()
  3. プログラムを使用Runtime.getRuntime().exec()して呼び出すechoと、リストが続きます。

+1 に @eis

于 2012-11-01T07:49:41.837 に答える
2

前述のインタビューの質問は非常にひねくれたもの (つまり人為的) であり、それを解決するには純粋な Java の外に出る必要があります。これは確かに、通常の状況で行うことを検討するものではありません。

他の答えはあなたにいくつかの半解決策を与えました...本当に、本当にこれをしなければならないなら。(アプリケーションの stdout / stderr ストリームがコンソール以外の場所にリダイレクトされた場合をほとんど扱っていないため、半解決策と言います。そして、それがこの問題の唯一の「本当の」側面です...)

(JDK 6 で) System クラスを使用できる場合...コンソールに出力するクリーンな方法 (たとえば、System.outリダイレクトされた場合) は、System.console()メソッドをConsole使用してオブジェクトを取得し、それを使用してWriter.

ただし、JVM にコンソールが関連付けられていない場合、console()は を返すことに注意してくださいnull


質問は実際には -- なぜ Java は私たちに PrintStream オブジェクト System.out を与えたのですか?? から始まりました。そして、なぜそれは最終的なのですか?? コンソールに何かを印刷する他の方法はありませんか??

答えは次のとおりです。

  1. 便宜上。
  2. そのため、ランダムなコードが誤ってそれを壊してしまうことはありません。(または、JVM で実行されている信頼できないコードについて心配する必要がある場合は、意図的に。) しかし、信頼できるコードは、実際にはを呼び出すことで変更できます。これは、変数の状態を安全に変更するために、舞台裏でいくつかの魔法を行います。(JIT コンパイラーはこれを認識しており、これら 3 つの変数を異なる方法で処理していると思います。)System.outSystem.setOut(...)finalfinal
  3. はい。上記と(うーん!)他の回答を参照してください。
于 2012-11-01T07:49:51.967 に答える
2

JDK のロガー(java.util.logging.Logger)を使用できます。

これは、Java クラスでロガーを作成する方法です。

import java.util.logging.Logger;

private final static Logger LOGGER = Logger.getLogger(MyClass.class .getName()); 

また、同じ目的で log4j を使用することもできます。

于 2012-11-01T07:37:51.123 に答える
1

文書が言うように、

Systemクラスには、いくつかの便利なクラスフィールドとメソッドが含まれています。インスタンス化できません。

ご覧のとおり、Systemクラスは、さまざまな便利な関数の一種のコンテナです。このフィールドとメソッドはすべて静的であるため、拡張する理由はありません。
Javaはstatic PrintStream out、コンソールを使用してプログラムと通信するためのデフォルトの方法であるため、私たちに提供します。
あなたが私に同意しないなら、教えてください。

于 2012-11-01T07:47:48.457 に答える
0

今日、その質問を達成する方法を見つけました。この回答には org.apache.log4j を使用しています。ここで多くの人が言っているように、他にも多くの方法があります。ありがとう。

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

public class HelloByLogger {

    private final static Logger logger = Logger.getLogger(HelloByLogger.class);

    public static void main(String[] args) {

        BasicConfigurator.configure();

        logger.info("From Logger... Ola!");

    }
}
于 2016-07-15T09:47:58.417 に答える