2016-10-05 11 views
0

travail sur cette bibliothèque une classe où je dois désactiver tampon sur stderr et stdout, si les importations de clients cette classe, en utilisant quelque chose commePossibilité d'exécuter le code simplement en important la classe en Java?

// stderr 
FileOutputStream fderr = new FileOutputStream(FileDescriptor.err); 

// stdout 
FileOutputStream fdout = new FileOutputStream(FileDescriptor.out); 

// stderr buffer of size 1 
BufferedOutputStream errBuf = new BufferedOutputStream(fderr, 1); 

// stdout buffer of size 1 
BufferedOutputStream outBuf = new BufferedOutputStream(fdout, 1); 

// add more features and functionality to stderr and stdout 
PrintStream errStream = new PrintStream(errBuf); 
PrintStream outStream = new PrintStream(outBuf); 

// update stderr and stderr 
System.setErr(errStream); 
System.setOut(outStream); 

Entré dans static initializers, mais malheureusement, ils ne fonctionnent qu'en particulier circumstances, aucun d'entre eux ne m'intéresse. Est-il possible en Java de faire exécuter le code ci-dessus uniquement en important la classe conteneur (c'est-à-dire, juste l'instruction import, sans invoquer aucune méthode, etc.)?

+0

Non seulement par l'importation, je pense, vous devez examiner les annotations, peut-être écrivez votre propre. – Shadov

+6

Les instructions 'import' n'ont aucun effet sur l'exécution, elles ne servent que le compilateur pour la résolution de noms. Mais même si cela fonctionnait, ce serait une bonne idée parce que l'indicateur de l'IDE supprime automatiquement les instructions d'importation inutilisées. –

Répondre

4

Vous regardez au mauvais endroit.

Si vous voulez que votre application envoie tous les messages stdout/stderr dans un flux spécifique; alors vous voulez "simplement" contrôler cela au niveau "JVM startup". En d'autres termes: vous devriez chercher des moyens de manipuler la JVM le plus tôt possible.

Vous ne voulez pas que cette redirection soit mise en place lorsque certaines de vos classes sont "importées"; vous voulez avoir un moyen robuste de dire directement à la JVM au démarrage de le faire.

Mais bien sûr: le vraiment façon saine de faire de telles choses est d'utiliser un cadre de l'exploitation forestière qui permet un meilleur contrôle de ce qui se passe. Se connecter à stdout/stderr n'est pas une bonne approche en premier lieu! Edit: étant donné qu'il s'agit de «roues d'entraînement» pour les étudiants; puis mettez simplement une méthode d'installation statique dans certaines de vos classes de bibliothèque (idéalement, en prenant pour les chaînes qui indiquent les noms de fichiers vers lesquels stdout/stderr doit aller); et instruire vos élèves à appeler cette méthode comme première chose dans leurs méthodes principales.

+0

C'est en fait motivé par la pédagogie que nous fournissons cette bibliothèque comme roues de formation au début. Ce n'est pas que nous dévaluons l'apprentissage de la mise en mémoire tampon des flux, mais plutôt que nous ne voulons pas que les étudiants fassent l'expérience/se soucient de la mise en mémoire tampon, spécialement au début, pour plus de simplicité. Pour la même raison, un cadre de journalisation n'est probablement pas une option pour nous non plus. Mais merci pour l'entrée! – Kareem

+0

Je vois; mis à jour ma réponse en conséquence. – GhostCat

+0

On dirait qu'il n'y a pas de façon plus simple! Merci! – Kareem

1

Les importations ne sont utilisées qu'au moment de la compilation.

Vous dites que les initialiseurs statiques ne présentent aucun intérêt. Toutefois, les initialiseurs statiques exécutent lorsque votre classe est chargée. Il n'y a aucun moyen de contourner cela, vous ne pouvez pas exécuter le code de votre classe sans qu'il soit chargé, donc je dirais que les initialiseurs statiques sont exactement ce que vous voulez.

Le client peut charger une classe sans avoir à instancier, par exemple en utilisant Class.forName

Exemple

public class Foo 
{ 
    static 
    { 
     System.out.println("Class foo loaded"); 
    } 
} 

// different file... 
public class Client 
{ 
    static 
    { 
     try { 
      Class.forName("Foo"); 
     }catch (ClassNotFoundException e) { 
      // TODO 
     } 
    } 
    public static void main (String args[]) { 
    // Nothing to do in this demo. The static intitizlier in 
    // this class causes Foo to be loaded and thus invokes Foo's 
    // static initializer 
    } 
}