6

私のプログラムでは、実行可能ファイルからアサート (false と評価される) を作成しましたが、アサートに関するコンソール出力は表示されません。アサートが偽かどうかを知りたいのですが、ランナブルがスローされたアサートをすべてキャッチしているように見えますか?

以下は、デモンストレーションのために私が書くことができる最も単純なサンプル プログラムです。(アサーションが有効になっています。そうでない場合、プログラムは異なる動作をし、1 行だけではなく両方の行を出力します)。プログラムの出力は次のとおりです。

False をアサートしようとしています

それでおしまい。その後、 assert ステートメントがスローされ、何かに引っ掛かりますが、それについてはわかりません。それについて知りたいのですが、何が間違っていますか?

import java.nio.ByteBuffer;
import java.util.concurrent.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import java.awt.FlowLayout;
import javax.swing.*;

class App
{
  private static final ScheduledExecutorService sExecutor =
    Executors.newSingleThreadScheduledExecutor();

  // Main
  public static void main(String[] args)
  {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() { createAndShowGUI(); } });

  }

  // Swing GUI
  private static void createAndShowGUI()
  {
    // Just create a swing thing. Boring
    JFrame frame = new JFrame("Title String");
    JLabel label = new JLabel("Hello World");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(label);
    frame.getContentPane().setLayout(new FlowLayout());
    frame.pack();
    frame.setVisible(true);

    // ********************************************
    // INTERESTING CODE HERE. We schedule a runnable which assert's false
    // but we never see a console assert error!
    // ********************************************
    sExecutor.schedule(new Runnable()
      { @Override public void run() { doAssertFalse(); }}, 0, TimeUnit.SECONDS);

  }

  public static void doAssertFalse()
  {
    System.out.println("About to assert False");
    assert false;
    System.out.println("Done asserting False");
  }
}
4

2 に答える 2

3

これはそれを行います:

private static final ScheduledExecutorService sExecutor =
        Executors.newSingleThreadScheduledExecutor();

// Main
public static void main(String[] args)
{
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            try {
                createAndShowGUI();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } });

}

// Swing GUI
private static void createAndShowGUI() throws ExecutionException, InterruptedException {
    // Just create a swing thing. Boring
    JFrame frame = new JFrame("Title String");
    JLabel label = new JLabel("Hello World");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(label);
    frame.getContentPane().setLayout(new FlowLayout());
    frame.pack();
    frame.setVisible(true);

    // ********************************************
    // INTERESTING CODE HERE. We schedule a runnable which assert's false
    // but we never see a console assert error!
    // ********************************************
    ScheduledFuture<?> future = sExecutor.schedule(new Runnable() {
        @Override
        public void run() {
            doAssertFalse();
        }
    }, 0, TimeUnit.SECONDS);
    future.get();

}

public static void doAssertFalse()
{
    System.out.println("About to assert False");
    assert false;
    System.out.println("Done asserting False");
}

scheduleの結果をScheduledFuture変数に保存していることに注意してください。Future でメソッドを呼び出すまで、例外は返されませんget()。すべての例外は、 にラップされてスローされますExecutionException

残念ながら、これはブロックされるため、例外を取得する別の方法は次のとおりです。

// Swing GUI
private static void createAndShowGUI() {
    // Just create a swing thing. Boring
    JFrame frame = new JFrame("Title String");
    JLabel label = new JLabel("Hello World");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(label);
    frame.getContentPane().setLayout(new FlowLayout());
    frame.pack();
    frame.setVisible(true);

    // ********************************************
    // INTERESTING CODE HERE. We schedule a runnable which assert's false
    // but we never see a console assert error!
    // ********************************************
    sExecutor.schedule(new Runnable() {
        @Override
        public void run() {
            try {
                doAssertFalse();
            } catch (Error e) {
                e.printStackTrace();
            }
        }
    }, 0, TimeUnit.SECONDS);

}

public static void doAssertFalse() {
    System.out.println("About to assert False");
    assert false;
    System.out.println("Done asserting False");
}

例外ではなく、エラーをキャッチしていることに注意してください。私がこれを行っているのは、アサーションが *Exception ではなく java.lang.AssertionError をスローするためです。

これらのことを行わない限り、ScheduledExecutorService が例外を飲み込むと言っている Javadoc のドキュメントを見つけるのに苦労していますが、私のテストではそうであると思われます。

于 2013-01-15T19:27:13.243 に答える
0

スレッドは例外を除いて何もしません(どうすればよいですか?STDERRまたはSTDOUTを使用せずにデータベースにログを記録する場合、Thread.run()は例外をログに記録する場所または例外を誰に再スローするかをどのように知ることができますか?)

使用できるThread.UncaughtExceptionHandlerがあり、そうすると、Assertsがそれを処理する必要があります。

問題は、Assertのメカニズムが例外を使用しているため、例外について事前に定義されたルールに従う必要があることだと思います。個人的には、Assertが単にスタックダンプを出力してexit(0)を実行したかどうかは気になりません。とにかくその例外をキャッチするべきではないからですが、それが何であるかです。

アプリ内のすべてのスレッドに対してThread.setDefaultUncaughtExceptionHandlerを1回だけ使用することもできることに注意してください(「DEFAULT」に注意してください)...これはかなり良い一般的な解決策になるはずです。

importjava.lang。*;

パブリッククラスThreadDemo{

   public static void main(String [] args){

     スレッドt=new Thread(new adminThread());

     t.setUncaughtExceptionHandler(新しいスレッド。
     UncaughtExceptionHandler(){
        public void uncaughtException(Thread t2、Throwable e){
           System.out.println(t2 + "は例外をスローします:" + e);
        }
     });
     //これはrun()関数を呼び出します
     t.start();

   }
}

クラスadminThreadはRunnable{を実装します

   public void run(){
      assert(false);
      新しいRuntimeException();をスローします。
   }
}

これを「通常」実行すると、RuntimeExceptionがスローされたことが示されます。「-ea」オプションを指定して実行すると、AssertExceptionが表示されます。試してみる。

于 2013-01-15T21:20:42.433 に答える