架构之旅
源码之 Java 基础
从 Hello, World! 说起
Hello, World! 之 标准输入流
从 流 到 Java IO
pulsar 文档
pulsar 本地开发集群搭建
jvm - sandbox
流量回放流程分析
nacos 笔记
nacos server 启动流程
nacos 集群管理 - ServerMemberManager
dubbo 之 No provider available for the service
-
+
首页
从 Hello, World! 说起
# 从 Hello, World! 说起 下面是一个很简单的 Hello, World! 程序 ```java public class Main { public static void main(String[] args) { System.out.println("Hello, World!"); } } ``` 至于这里的,public 、class 、void 、main 等都是很基础的内容,暂不在讨论范围内, 我们先从最核心的这行 `System.out.println("Hello, World!");` 开始说起吧。 这行,主要是调用 System 这个类里 out 对象的 println 方法,最后的 Hello, World! 是个字符串。 我们先看下 System 这个类吧: ## System 类 ```java /** * The <code>System</code> class contains several useful class fields * and methods. It cannot be instantiated. * * <p>Among the facilities provided by the <code>System</code> class * are standard input, standard output, and error output streams; * access to externally defined properties and environment * variables; a means of loading files and libraries; and a utility * method for quickly copying a portion of an array. * * @author unascribed * @since JDK1.0 */ public final class 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(); } /** Don't let anyone instantiate this class */ private System() { } ``` 以上,我们可以看到 System 类包含了几个有用的字段和方法,并且不能被实例化。 System 类提供的工具包括: 1. 标准输入、标准输出、以及错误输出流; 2. 访问外部定义的属性和环境变量; 3. 一种加载文件和库的方法; 4. 以及一个用于快速复制数组一部分的实用方法。 ## 标准输入 我们再看看这里提到的标准输入: ```java /** * 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 void checkIO() { SecurityManager sm = getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("setIO")); } } private static native void setIn0(InputStream in); ``` setIn 方法用于重新设置标准输入流,首先,如果有安全管理类,那么这个类的 checkPermission 方法将会被调用,以便检查是否拥有 setIO 的运行时权限,如果这个安全管理类存在,且其 checkPermission 方法不允许重新设置标准输入流,则抛出异常。下面,我们看看 getSecurityManager 吧 ## SecurityManager ```java /** * Sets the System security. * * <p> If there is a security manager already installed, this method first * calls the security manager's <code>checkPermission</code> method * with a <code>RuntimePermission("setSecurityManager")</code> * permission to ensure it's ok to replace the existing * security manager. * This may result in throwing a <code>SecurityException</code>. * * <p> Otherwise, the argument is established as the current * security manager. If the argument is <code>null</code> and no * security manager has been established, then no action is taken and * the method simply returns. * * @param s the security manager. * @exception SecurityException if the security manager has already * been set and its <code>checkPermission</code> method * doesn't allow it to be replaced. * @see #getSecurityManager * @see SecurityManager#checkPermission * @see java.lang.RuntimePermission */ public static void setSecurityManager(final SecurityManager s) { try { s.checkPackageAccess("java.lang"); } catch (Exception e) { // no-op } setSecurityManager0(s); } private static synchronized void setSecurityManager0(final SecurityManager s) { SecurityManager sm = getSecurityManager(); if (sm != null) { // ask the currently installed security manager if we // can replace it. sm.checkPermission(new RuntimePermission ("setSecurityManager")); } if ((s != null) && (s.getClass().getClassLoader() != null)) { // New security manager class is not on bootstrap classpath. // Cause policy to get initialized before we install the new // security manager, in order to prevent infinite loops when // trying to initialize the policy (which usually involves // accessing some security and/or system properties, which in turn // calls the installed security manager's checkPermission method // which will loop infinitely if there is a non-system class // (in this case: the new security manager class) on the stack). AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { s.getClass().getProtectionDomain().implies (SecurityConstants.ALL_PERMISSION); return null; } }); } security = s; } /** * Gets the system security interface. * * @return if a security manager has already been established for the * current application, then that security manager is returned; * otherwise, <code>null</code> is returned. * @see #setSecurityManager */ public static SecurityManager getSecurityManager() { return security; } ``` 这里,get 方法很简单,而 set 方法则先检查是否可以访问 java.lang 包,至于 checkPackageAccess 之后再讨论,setSecurityManager0 方法是真正重新设置 SecurityManager 的,它先检查当前是否已经存在 SecurityManager ,如果存在,则 调用 它的方法 判断是否允许重新设置 SecurityManager,如果允许,且新的 SecurityManager 不为空,则重新设置,否则啥也不做。类加载,以及安全相关的问题,我们后面再讨论。 标准输入流,可能又是一个很长的故事,我们下节继续。
十三
2021年3月11日 00:50
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
关于 MrDoc
觅思文档MrDoc
是
州的先生
开发并开源的在线文档系统,其适合作为个人和小型团队的云笔记、文档和知识库管理工具。
如果觅思文档给你或你的团队带来了帮助,欢迎对作者进行一些打赏捐助,这将有力支持作者持续投入精力更新和维护觅思文档,感谢你的捐助!
>>>捐助鸣谢列表
微信
支付宝
QQ
PayPal
Markdown文件
分享
链接
类型
密码
更新密码