2016-06-06 3 views
2

У меня есть код обработки 3, который демонстрирует нечетное поведение. У меня есть определенный метод void exit(), который выполняется в произвольные моменты времени, без того, что пользователь действительно сообщает, что код должен выйти. Вот способ:exit() метод введен без команды 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(); 
} 

Как вы можете видеть, единственное, что он делает, это попытка закрыть буферизованный писатель, называемый выводом. Попытка этого писателя не имеет решающего значения, так что теперь я просто удаляю его из своего эскиза. Но в долгосрочной перспективе мне любопытно, как это может происходить. Нигде в моем коде не вызывается метод exit. IE, код не может решить выйти. Только когда пользователь закрывает проблему, используя X.

Примечание: я не могу загрузить весь код, этот метод также подключен, потому что он слишком длинный. Я думаю, что, возможно, лучший способ рассказать о моих вопросах будет примерно таким:

«Привет, я noob, который ничего не знает о методе выхода. Есть ли способ, чтобы этот метод каким-то образом вызывался без меня явно вызывая его или нажав кнопку выхода? "

+2

Что код выполняется? – zubergu

+2

Вы переопределяете метод parent exit()? –

+2

Можете ли вы предоставить [mcve], который проявляет проблему? –

ответ

3

Добавить это в начале вашего метода exit().

new Exception().printStackTrace(); 

Полученный StackTrace позволит вам выяснить, что вызова метода exit().

Если вы не можете настроить код, вы можете запустить приложение с помощью отладчика и установить точку останова в начале метода exit().

Чтобы ответить на ваш вопрос о том, возможно ли, ответ зависит от того, что вы подразумеваете под «без явного вызова». Существуют различные способы вызова метода, некоторые из которых довольно неясны; например

  • Вы можете использовать отражение, чтобы получить Method объект для exit метода из объявляющего класса, а затем вызвать invoke(...) на него.
  • Вы можете вызвать метод Java из собственного кода через JNI или JNA apis.
  • Вы можете создать исходный код Java, содержащий вызов exit(), скомпилировать его, загрузить и запустить.
  • Вы можете вставить вызов exit() в «невинный» метод с использованием BCEL или аналогичного.

И ...

  • Если есть отладочный агент присоединен к JVM, отладчик может назвать exit() на какой-нить в JVM.
+0

Спасибо! Я добавлю это и посмотрю, что происходит. Понятно, что общая проблема заключается в том, что этот метод более сложный, чем я думал! – Murenrb

0

Короче говоря, ответ на ваш вопрос: Да.

Ваш метод может быть найден и вызван динамически с использованием отражения любым классом в том же загрузчике классов или другом, что ниже в иерархии.

Кроме того, он имеет доступ по умолчанию. Таким образом, он может быть вызван статически любым классом в одном пакете.

+0

Может быть объяснено, пожалуйста? – Andres

+0

Я очень ценю ответ! Можете ли вы расширить это?что вы имеете в виду «использование отражения любым классом» или «доступ по умолчанию». Каков правильный способ его реализации, чтобы этого не произошло? – Murenrb

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"); 
    } 
} 
0

Это специфичная для обработки вещь.

void exit() представляет собой метод уже определена путем обработкой в ​​PApplet.java

Как объяснен в reference:

Вместо того, чтобы немедленно завершение, выход() приведет к тому, эскизу к выходу после розыгрыша () завершено (или после завершения установки(), если вызвано во время функции setup()).

Для программистов на Java это не то же самое, что System.exit(). Кроме того, System.exit() не следует использовать, поскольку при закрытии приложения при запуске draw() может произойти сбой (в частности, с P3D).

exit() предполагается использовать что-то вроде этого:

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

void mousePressed() { 
    exit(); 
} 

Это называется в PApplet.java в нескольких местах, в частности в handleKeyEvent, чтобы закрыть эскиз, когда ESC нажата, или когда ⌘w является нажат.

Просто переименуйте свой метод к чему-то, кроме выхода()

+0

Проблема в том, что мне нужен метод для запуска при выходе, если не нажата конкретная кнопка или что-то еще. IE, я думаю, я хочу использовать метод PApplet.java. У пользователя нет возможности закрыть код при нормальной работе. Но если скрипт закрыт с помощью кнопки X или что-то в этом роде, я хочу убедиться, что вы сбросили. CSV-записи. – Murenrb