__RIGA__ equivalenti in Java?

Sto cercando un modo per includere __LINE__ come una costante della fase di compilazione in uscita messaggi.

Varie soluzioni sembrano non esistere, ma con un grande runtime pena come suggerito in __LINE__) in JS e __LINE__) in C#. Di solito sono sempre basate su un oggetto di runtime StackFrame come log4j.

Utilizzando il log4j possibilità di attivazione/disattivazione di un bisogno, non è un’opzione, dal momento che, di solito, quando si verifica un errore, è troppo tardi per attivare i numeri di riga, e sostituite il codice non sembra avere il numero di linea più.
. Sarebbe possibile :

  1. Pre-elaborare i file sorgente java prima della compilazione, idealmente con qualcosa di integrato con Eclipse1, in modo che possa essere testato sulla developpement piattaforma.
  2. Essere in grado di pre-processo la classe al momento del caricamento. L’overhead, quindi, sarebbe trascurabile per essere ammortizzati.

1. In realtà io uso un brutto hack: chiamata di un preprocessore personalizzato solo dopo il checkout sul server di generazione di via FORMICA trucchi

  • Solo per mia curiosità: Perché hai bisogno del numero di riga nel log? Quando si verifica un errore, si ha la completa stacktrace, che indica il numero di riga…
  • A volte l’eccezione, invece, il numero di linea ho qualcosa di simile Util.java(Inlined Compiled Code). E a volte non ho alcuna eccezione, a registrare le informazioni : “essere qui”, “essere qui”, non ho voglia di preoccuparsi messaggi univoci (il numero di linea che li rende unici in ogni caso)
  • La JVM deve essere in grado di gestire la situazione. Che versione di Java hai?
  • Per romaintaz domanda: siamo Noi a creare la GWT applicazione, che è Javascript compilato da Java. Durante la compilazione, di classe i nomi e i numeri di riga sono perso, quindi la traccia dello stack dà informazioni inutili. Punti me compilato il codice Javascript, ma è difficile o impossibile trovare il corrispondente codice Java da esso.
  • Nota – a partire dal 2016 moderne versioni di Java non gettare numero di riga quando inline.
InformationsquelleAutor Steve Schnepp | 2009-08-28



7 Replies
  1. 9

    Se si compila con il debug=line opzione, la linea di informazioni presente nel file di classe, ma la VM può buttare via in fase di runtime. Questo dipende da alcune opzioni che è possibile specificare quando si avvia il programma Java. Di solito, la pena di prestazioni per l’esecuzione del debug infos è di circa il 5%, oltre a un po ‘ più di memoria in perm gen spazio. Dal momento che questa informazione è preziosa, non vedo il motivo per rimuovere queste informazioni.

    Il tuo commento (Util.java(Inlined Compiled Code)) suggeriscono che si sta utilizzando aggressivo ottimizzazioni. Se si può trasformare quelle off. In questo modo, si può semplicemente:

    //For Java 1.4, use new Exception().getStackTrace()
    int line = Thread.currentThread().getStackTrace()[0].getLineNumber();

    quando ne hai bisogno (ad esempio all’interno di catch o if (log.isInfoEnabled())).

    Come per __LINE__, il compilatore Java non ha il supporto per questo. L’unica opzione è quella di utilizzare alcuni trucchi per filtrare la fonte. Suggerisco di definire una variabile int __LINE__ da qualche parte e impostare qualche valore casuale (0 di essere abbastanza casuale) quando ne avete bisogno. Quindi scrivere un filtro che sostituisce il numero di __LINE__ = \d+ con il numero di riga corrente. Questo permette di fissare il numero di riga in luogo.

    • Perché new Exception().getStackTrace() piuttosto che Thread.currentThread().getStackTrace()?
    • Non la ragione, ma il fatto che non mi sono preoccupato di cercare il Thread di classe per come ottenere il corrente dello stack e sapevo che un’Eccezione è 🙂
    • +1 per una soluzione che potesse essere utilizzato anche sul mio dev ambiente (basta cercare&sostituire Thread.... con il numero di riga nel processo di generazione)
    • Thread.currentThread().getStackTrace() sembra non esiste in 1.4.2… new Exception().getStackTrace() sarà poi. E sostituito a tempo di compilazione con il reale numero di riga per la produzione.
    • Perché dici Thread.currentThread().getStackTrace()[0].getLineNumber(); mentre la risposta qui sotto dice Thread.currentThread().getStackTrace()[2].getLineNumber(); e un’altra risposta al di sotto di utilizzare getStackTrace()[3] ? Inoltre, ho cercato nel mio codice, ho trovato un messaggio con il numero di riga=1503 mentre è in realtà la linea 20 nel file di origine. Perché è che?
    • Probabilmente dipende dal tuo codice e la Java VM. Guardare gli altri valori del StackFrame per vedere in che classe/metodo con il numero di riga. Che dovrebbe darvi un’idea di come risolvere il problema.

  2. 13

    È impossibile ottenere l’effetto di __LINE__ in C che avviene in fase di compilazione.

    È possibile ottenere il numero di riga chiamando una funzione come questa in fase di runtime,

    public static int lineNumber() {
        return Thread.currentThread().getStackTrace()[2].getLineNumber();
    }
    • Il debug-informazioni su la linea deve essere compilato nel file di classe, per accedere a queste informazioni.
  3. 6

    Ho trovato questa classe rende le cose facili, se siete alla ricerca per “got to qui, ottenuto qui” tipo di registrazione. Ho un file Here.java che mi aggiungi a i miei progetti, che contiene la seguente definizione di classe:

    public class Here {
        public static String at () {
            StackTraceElement ste = Thread.currentThread().getStackTrace()[3];
            String where = ste.getClassName() + " " + ste.getMethodName() + " " + ste.getLineNumber() + " ";
            return where;
        }
    }

    Utilizzare nella sua forma più semplice:

    Log.v(TAG, Here.At());

    O, se volete vedere altre cose:

    Log.v(TAG, Here.At() + String.format("interesting value = %d", my_val));

    Questo darebbe “com.otherpackagenamestuff.MyClass myMethod 225″ nel primo caso, e lo stesso, ma con interessanti value = 123” aggiunto nel secondo caso.

    • Io uso lo stesso trucco per ottenere il numero di riga. A seconda di come il metodo codificato, l’indice può essere necessario 2 invece di 3.
  4. 1

    Vorrei utilizzare una registrazione framework per questo, e lasciate che fare con i dettagli disordinati. Sia java.util.la registrazione e logback può facilmente visualizzare le informazioni sul chiamante simile a quello che LINEA in grado di fornire.

    Il vantaggio principale è che l’informazione è calcolato solo se necessario, in modo da non emettere significa nessun sovraccarico.

  5. 0

    Out of the box non credo che Java offre ciò di cui avete bisogno.

    Tuttavia, se si dovesse scrivere la tua annotazione del processore e la Java 6.0 compilatore Api penso che si possa risolvere questo problema. Io non la cura per indovinare di quanto lavoro ci sarebbe da fare così.

    Nota che Eclipse consente di includere la vostra annotazione di elaborazione nella sua costruzione meccanismo.

  6. 0

    Non so una cosa del genere in Java compilatore. Ma si può scrivere un semplice programma, che sostituisce un token come __LINE__ con il numero di riga nel file e configurare il buildprocess per eseguire questo strumento prima di procedere alla compilazione. Una sorta di un preprocessore.

    • Che è esattamente quello che vorrei sostituire (vedere nota 1.)

Lascia un commento