exit()方法在没有exit命令的情况下输入

时间:2016-06-06 13:26:45

标签: processing exit

我有处理3代码表现出一些奇怪的行为。我定义了一个void exit()方法,该方法是在随机时间执行的,用户实际上并没有告诉代码退出。这是方法:

void exit()
{
 println("clearing buffer and closing file");
 if (output != null) {
   print("output is not null");
   try {
     output.close();
   } 
   catch (IOException e) {
     println("Error while closing the writer");
   }
 }
 super.exit();
}

正如您所看到的,它唯一能做的就是尝试关闭一个名为output的缓冲编写器。冲洗这位作家并不重要,所以现在我只是从草图中删除它。但从长远来看,我很好奇这是怎么回事。我的代码中没有其他地方显式调用的exit方法。 IE,代码无法决定退出。仅当用户使用X关闭问题时才会这样做。

注意:由于太长,我无法上传此方法所附的整个代码。我想也许更好的方式来表达我的问题就像是:

“嗨,我是一个对退出方法一无所知的菜鸟。无论如何,如果没有我明确地调用它或点击退出按钮,这个方法可以以某种方式调用吗?”

4 个答案:

答案 0 :(得分:3)

exit()方法的开头添加此内容。

    new Exception().printStackTrace();

生成的堆栈跟踪应该可以让您找出调用exit()方法的内容。

或者,如果您无法调整代码,可以使用调试器运行应用程序,并在exit()方法的开头设置断点。

要回答你关于是否可能的问题,答案取决于你的意思是“没有我明确地打电话”。有多种方法可以调用方法,其中一些方法非常模糊;例如

  • 您可以使用反射从声明类中获取Method方法的exit对象,然后在其上调用invoke(...)
  • 您可以通过JNI或JNA apis从本机代码调用Java方法。
  • 您可以生成包含exit()调用的Java源代码,编译它,加载它并运行它。
  • 您可以使用BCEL或类似方法将exit()调用插入“无辜”方法。

而且......

  • 如果有一个调试代理连接到JVM,调试器可以在JVM中的某个线程上调用exit()

答案 1 :(得分:0)

简而言之,您的问题的答案是肯定的。

可以使用同一类加载器中的任何类或层次结构中下面的任何其他类,使用反射动态查找和调用您的方法。

此外,它还具有默认访问权限。所以它可以由同一个包中的任何类静态调用。

答案 2 :(得分:0)

+1 @Andres,反射是一种可能性。

您是否尝试在方法上使用断点并查看线程的堆栈跟踪?

我个人不会使用断点(只是我的风格),并会尝试以编程方式查看该线程。也许以下一些代码可以帮助您查看该主题并了解正在进行的操作:

public class ThreadUtil {

    /** Blocked constructor **/
    private ThreadUtil() {
    }

    /**
     * Get the stackstrace of the current {@link Thread}.
     * The stacktrace will be returned in the form of a string.
     */
    public static String getStackTrace() {
        return getStackTrace(Thread.currentThread());
    }

    /**
     * Get the stackstrace of a {@link Thread}.
     * The stacktrace will be returned in the form of a string.
     */
    public static String getStackTrace(Thread thread) {
        StringBuilder sb = new StringBuilder();
        StackTraceElement[] currThreadStackTraceElementList = thread.getStackTrace();
        appendStackTrace(sb, currThreadStackTraceElementList);
        return sb.toString();
    }

    public static String getAllStackTraces() {
        StringBuilder sb = new StringBuilder();
        Map<Thread, StackTraceElement[]> threadList = Thread.getAllStackTraces();
        for (StackTraceElement[] currThreadStackTraceElementList : threadList.values()) {
            appendStackTrace(sb, currThreadStackTraceElementList);
        }
        return sb.toString();
    }

    private static void appendStackTrace(StringBuilder sb,
            StackTraceElement[] currThreadStackTraceElementList) {
        sb.append("Thread stack trace: \n");
        for (StackTraceElement currThreadStackTraceElement : currThreadStackTraceElementList) {
            sb.append("\t" + currThreadStackTraceElement + "\n");
        }
        sb.append("\n");
    }
}

答案 3 :(得分:0)

这是特定于处理的事情。

void exit()是已经通过PApplet.java

中的处理定义的方法

正如reference

中所述
  

而不是立即终止,exit()将导致草图   draw()完成后退出(如果调用则在setup()完成后退出)   在setup()函数期间)。

     

对于Java程序员,这与System.exit()不同。进一步,   不应使用System.exit()因为关闭应用程序   而draw()正在运行可能会导致崩溃(特别是对于P3D)。

exit()预计会使用以下内容:

void draw() {
  line(mouseX, mouseY, 50, 50);
}

void mousePressed() {
  exit(); 
}

PApplet.java内的某些地方调用它,特别是handleKeyEvent,以便在按下ESC或按下⌘w时关闭草图。

只需将您的方法重命名为exit()

以外的其他内容