Maison  >  Questions et réponses  >  le corps du texte

通过Java IO流的形式实现键盘录入的疑问

巴扎黑巴扎黑2742 Il y a quelques jours502

répondre à tous(2)je répondrai

  • ringa_lee

    ringa_lee2017-04-18 10:56:47

    Étant donné que System.in est une instance InputStream statique, vous pouvez consulter la documentation de l'API Java

    répondre
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:56:47

    Tout d'abord, System.in est un objet de type InputStream, qui ressemble à ceci dans le code source :

    /**
     * The "standard" input stream. This stream is already
     * open and ready to supply input data. Typically this stream
     * corresponds to keyboard input or another input source specified by
     * the host environment or user.
     */
    public final static InputStream in = null;

    On peut voir que System.in appartient à l'entrée standard et que les données peuvent être saisies via le clavier ou d'autres méthodes.
    Mais dans le code source, cet objet ne possède pas de méthode d'initialisation (explicite). En lisant le code source, vous pouvez retrouver la méthode suivante :

    /**
     * Reassigns the "standard" input stream.
     *
     * <p>First, if there is a security manager, its <code>checkPermission</code>
     * method is called with a <code>RuntimePermission("setIO")</code> permission
     *  to see if it's ok to reassign the "standard" input stream.
     * <p>
     *
     * @param in the new standard input stream.
     *
     * @throws SecurityException
     *        if a security manager exists and its
     *        <code>checkPermission</code> method doesn't allow
     *        reassigning of the standard input stream.
     *
     * @see SecurityManager#checkPermission
     * @see java.lang.RuntimePermission
     *
     * @since   JDK1.1
     */
    public static void setIn(InputStream in) {
        checkIO();
        setIn0(in);
    }
    
    private static native void setIn0(InputStream in);

    La lecture des commentaires montre que cette méthode est utilisée pour définir
    En étudiant setIn0(in), on voit que cette méthode réalise la configuration de in en appelant l'interface sous-jacente. Alors comment est-elle initialisée lorsque le logiciel est lancé. en cours d'exécution?
    Il y a le code suivant dans la classe System :

    /* register the natives via the static initializer.
     *
     * VM will invoke the initializeSystemClass method to complete
     * the initialization for this class separated from clinit.
     * Note that to use properties set by the VM, see the constraints
     * described in the initializeSystemClass method.
     */
    private static native void registerNatives();
    static {
        registerNatives();
    }
    
    /**
     * Initialize the system class.  Called after thread initialization.
     */
    private static void initializeSystemClass() {
    ...
    FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
    FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
    FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
    setIn0(new BufferedInputStream(fdIn));
    setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
    setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
    ...
    }

    Il ressort de ce code que lorsque le logiciel est en cours d'exécution, il exécute d'abord le bloc de code statique et appelle la méthode sous-jacente registerNatives() pour initialiser la classe System. Cette méthode appelle la méthode initializeSystemClass() pour initialiser le System. Ces deux étapes sont toutes implémentées via VM, puis lisez la méthode initializeSystemClass(). Vous pouvez voir que trois morceaux de code sont appelés setIn0, setOut0 et steErr0, qui initialisent les trois flux de sortie d'entrée standard, de sortie standard, et erreur standard Jusqu'à présent, System.in, out, Le processus d'initialisation de err est clair.
    La méthode marquée comme native est une fonction implémentée par la JVM appelant d'autres codes. Cela a quelque chose à voir avec la couche inférieure. Je pense que cela donne l'impression que le Bootstrap Classloader est réellement implémenté en C, mais il est appelé par la JVM. pour charger chaque classe JAR de base, c'est similaire.
    De plus, vous avez dit qu'InputStream est une classe abstraite (interface). En fait, les classes d'interface et les classes abstraites peuvent être utilisées comme paramètres, mais l'implémentation n'est certainement pas implémentée par elles. être utilisé comme paramètres. Après tout, la classe parent apparaît là où les classes enfants peuvent être remplacées, donc il n'y a pas de problème ici

    répondre
    0
  • Annulerrépondre