• 深入了解 Java HelloWorld



    Java 的 Hello World 代码


    public class HelloWorld {
     
        /**
         * 
         * @param args
         */
     
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            System.out.println("Hello World");
        }
     
    }


    编译执行

    $ javac HelloWorld.java 
    $ java HelloWorld       
    Hello World

    功能就是在控制台打印 Hello World 字符串, 我们这里深入每个步骤,探讨是怎样将字符串打印到控制台的。

    环境

    我们刚才的程序执行在 Ubuntu Linux 的控制台 bash 程序里。 javac 是编译器。 java 执行虚拟机。加载 HelloWorld.class 执行 HelloWorld 类的 main 函数,这部分是属于虚拟机的内容,临时不做考虑,我们主要从代码调用的步骤分析。

    System 类

    从代码逻辑上,我们非常easy看出是 System 类的 out 成员 println 函数运行了打印操作:

    public final class System {
    
        /**
         * Default input stream.
         */
        public static final InputStream in;
    
        /**
         * Default output stream.
         */
        public static final PrintStream out;
    
        /**
         * Default error output stream.
         */
        public static final PrintStream err;
    
        private static final String lineSeparator;
        private static Properties systemProperties;
    
        static {
            err = new PrintStream(new FileOutputStream(FileDescriptor.err));
            out = new PrintStream(new FileOutputStream(FileDescriptor.out));
            in = new BufferedInputStream(new FileInputStream(FileDescriptor.in));
            lineSeparator = System.getProperty("line.separator");
        }
    


    out 是个 PrintStream

    PrintStream 类

        /**
         * Prints a string followed by a newline. The string is converted to an array of bytes using
         * the encoding chosen during the construction of this stream. The bytes are
         * then written to the target stream with {@code write(int)}.
         *
         * <p>If an I/O error occurs, this stream's error state is set to {@code true}.
         *
         * @param str
         *            the string to print to the target stream.
         * @see #write(int)
         */
        public synchronized void println(String str) {
            print(str);
            newline();
        }
    

    详细的工作交给了 print ,  我们在这个类里面能够看到 newline 仅仅是打印了两个特殊字符,换行。

        public synchronized void print(String str) {
            if (out == null) {
                setError();
                return;
            }
            if (str == null) {
                print("null");
                return;
            }
    
            try {
                if (encoding == null) {
                    write(str.getBytes());
                } else {
                    write(str.getBytes(encoding));
                }
            } catch (IOException e) {
                setError();
            }
        }

    进一步的工作由 write 函数完毕:
        public synchronized void write(int oneByte) {
            if (out == null) {
                setError();
                return;
            }
            try {
                out.write(oneByte);
                int b = oneByte & 0xFF;
                // 0x0A is ASCII newline, 0x15 is EBCDIC newline.
                boolean isNewline = b == 0x0A || b == 0x15;
                if (autoFlush && isNewline) {
                    flush();
                }
            } catch (IOException e) {
                setError();
            }
        }

    又来了个 out 这个。out 是 来自 OutputStream 的实现类 public class FileOutputStream extends OutputStream 

    public class FileOutputStream extends OutputStream {
    
        private FileDescriptor fd;
        private final boolean shouldClose;
    
        /** The unique file channel. Lazily initialized because it's rarely needed. */
        private FileChannel channel;
    
        /** File access mode */
        private final int mode;
    
        private final CloseGuard guard = CloseGuard.get();

    FileDescriptor

    public final class FileDescriptor {
    
        /**
         * Corresponds to {@code stdin}.
         */
        public static final FileDescriptor in = new FileDescriptor();
    
        /**
         * Corresponds to {@code stdout}.
         */
        public static final FileDescriptor out = new FileDescriptor();
    
        /**
         * Corresponds to {@code stderr}.
         */
        public static final FileDescriptor err = new FileDescriptor();
    
        /**
         * The Unix file descriptor backing this FileDescriptor.
         * A value of -1 indicates that this FileDescriptor is invalid.
         */
        private int descriptor = -1;
    
        static {
            in.descriptor = STDIN_FILENO;
            out.descriptor = STDOUT_FILENO;
            err.descriptor = STDERR_FILENO;
        }
    

    这里来到 STDOUT_FILENO。 该变量定义在: 在<stdio.h>。
    STDIN_FILENO等是文件描写叙述符,是非负整数,一般定义为0, 1, 2,属于没有buffer的I/O。直接调用系统调用。在<unistd.h>。

    參考i: http://blog.csdn.net/xiaoxi2xin/article/details/5524769
        @Override
        public void write(byte[] buffer, int byteOffset, int byteCount) throws IOException {
            IoBridge.write(fd, buffer, byteOffset, byteCount);
        }
    
        @Override
        public void write(int oneByte) throws IOException {
            write(new 

    最后是调用 os 的 write


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    Navicat将表转为模型
    RestTemplate Hashmap变为LinkedHashMap源码解读
    IDEA无法编译源码,IDEA查看源码出现/* compiled code */
    grep,egrep,正则表达式
    特殊权限
    更新系统硬件信息----光驱
    复制其他文件的权限做为自己的权限
    umask
    生成随机口令
    让新增用户默认拥有文件
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4625942.html
Copyright © 2020-2023  润新知