java.lang.System源码分析
1.final修饰,不能被继承。构造函数使用private修饰,不能被其他类实例化
public final class System { ... private System() { } ... }
2.成员变量:final修饰,不能被重新赋值
public final static InputStream in = null;// 标准输入流,默认已经打开,一般用来响应键盘或者其他用户指定的输入 public final static PrintStream out = null;// 标准输出流,默认已经打开,一般用来展示输出 public final static PrintStream err = null;// 标准错误输出流,默认已经打开,按照约定,用来输出错误信息 private static native void setIn0(InputStream in);// 初始化这些流的工作由本地native方法实现,由系统连接的共享库去实现 private static native void setOut0(PrintStream out); private static native void setErr0(PrintStream err); private static volatile SecurityManager security = null;// 系统安全管理器,使用volatile修饰该变量。在初始化IO流时,需要使用安全器校验权限 private static volatile Console cons = null;// 标准输出控制台
3.SecurityManager,安全管理器,用来做访问权限校验
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; } private static void checkIO() { SecurityManager sm = getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("setIO")); } } public void checkPermission(Permission perm) { java.security.AccessController.checkPermission(perm); }
4.Console 只能用在标准输入、输出流未被重定向的原始控制台中使用
public static Console console() { if (cons == null) { synchronized (System.class) { cons = sun.misc.SharedSecrets.getJavaIOAccess().console();// console是通过sun.misc.SharedSecrets 类获取得到的(作用是从JVM里面获取实例对象) } } return cons; }
5.获取系统时间,都是通过本地native方法实现
public static native long currentTimeMillis();// 获取毫秒级的时间戳(1970年1月1日0时起的毫秒数) public static native long nanoTime();// 获取纳秒,返回的可能是任意时间(主要用于衡量时间段)
6.数组拷贝
public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);
此方法在Collection的实现类里面扩容的时候经常被遇到,例如 ArrayList.add(int, E)。
还有另外一个比较常用的数组拷贝的方法:Arrays.copyOf,通过看源码会发现,最后实际调用的也是 Syetem.arraycopy 。
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { @SuppressWarnings("unchecked") T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }
7.获取对象的地址,本地native方法
public static native int identityHashCode(Object x);
当Object的hashCode()被重写的时候,如何获取到对象的地址呢?通过 System.identityHashCode(Object) 可以获取到对象的地址。
public class OverrideHashCode { @Override public int hashCode() { //return super.hashCode(); return 0; } } OverrideHashCode overrideHash = new OverrideHashCode(); System.out.println("覆盖之后,hashCode(): " + overrideHash.hashCode()); System.out.println("通过System.identityHashCode()重新获取对象地址: " + System.identityHashCode(overrideHash));
测试结果:
覆盖之后,hashCode(): 2018699554 // 未被重写 通过System.identityHashCode()重新获取对象地址: 2018699554 覆盖之后,hashCode(): 0 // 重写后的值 通过System.identityHashCode()重新获取对象地址: 2018699554
8.系统变量
private static Properties props; private static native Properties initProperties(Properties props);// 初始化是通过本地方法实现的 public static Properties getProperties() { SecurityManager sm = getSecurityManager(); if (sm != null) {// 获取系统变量的时候,需要做权限校验。如果没有权限,会抛出 AccessControlException sm.checkPropertiesAccess(); } return props; } public static void setProperties(Properties props) { SecurityManager sm = getSecurityManager(); if (sm != null) { sm.checkPropertiesAccess(); } if (props == null) { props = new Properties(); initProperties(props); } System.props = props; }
9.获取操作系统环境变量,用户自己配置的系统变量,也做了权限校验
public static String getenv(String name) { SecurityManager sm = getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("getenv."+name)); } return ProcessEnvironment.getenv(name); }
测试使用:
System.out.println(System.getenv("ROCKETMQ_HOME"));
能够获取,之前在Windows中设置的环境变量的值。
10.程序退出,接收一个参数status,0表示正常退出,非零参数表示非正常退出。不管status为何值都会退出程序。和return 相比,return是回到上一层,而System.exit(status)是回到最上层
public static void exit(int status) { Runtime.getRuntime().exit(status);// 实际上通过获取Runtime运行时来退出的 }
11.手动调用gc-垃圾回收器,注意调用后不会马上发生消息回收,JVM会在适合的时候触发GC
public static void gc() { Runtime.getRuntime().gc(); }
12.加载动态库(Windows下面是dll文件),用来装载库文件,不论是JNI库文件还是非JNI库文件
@CallerSensitive public static void load(String filename) {// fileName一定要是绝对路径,否则会抛出 UnsatisfiedLinkError Runtime.getRuntime().load0(Reflection.getCallerClass(), filename); } @CallerSensitive public static void loadLibrary(String libname) { Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname); }
好了,Syetem的代码就这么多~
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
北京房租大涨?6个维度,数万条数据帮你揭穿
昨天还幻想海边别墅的年轻人,今天可能开始对房租绝望了。 8月初,有网友在“水木论坛”发帖控诉长租公寓加价抢房引起关注。据说,一名业主打算出租自己位于天通苑的三居室,预期租金7500元/月,结果被二方中介互相抬价,硬生生抬到了10800。 过去一个月,全国热点城市的房租如脱缰野马。一线的房租同比涨了近20%。一夜醒来,无产青年连一块立锥之地都悬了。 从2018下半年开始,租金海啸汹汹来袭,资本狂欢,官方默然,房东纠结,租客尖叫。 这不是一方的过错,而更像是一场全社会的“集体谋杀作品”。最令人不安的是,过去房地产的那套玩法和上涨逻辑,今天正在转移到房租上。 房租暴涨的不只是北京。有数据显示,7月份北京、上海、广州、深圳、天津、武汉、重庆、南京、杭州和成都十大城市租金环比均有所上涨。其中北京、上海、深圳的租金涨幅最猛,北京7月份房租同比上涨3.1
- 下一篇
阿里的面试官都喜欢问哪些技术问题?
金九银十是招聘的旺季,小编在这里也给大家整理了一套阿里面试官最喜欢问的问题或者出场率较高的面试题,助校招或者社招路上的你一臂之力! 首先我们需要明白一个事实,招聘的一个很关键的因素是在给自己找未来的同事,同级别下要找比自己优秀的人,面试是一个双向选择的过程,也是一个将心比心去沟通的过程。 就像我们有的人感觉自己很牛逼,但是拿不到offer,而其他的人菜的一笔,却可以拿到offer,我们称之为玄学offer,遇到这种情况大家也不要感觉到有什么不可描述的心情,一切随缘即可! 和以前一样,只有问题没有参考答案,需要各位小伙伴下来逐一学习! 一、开场白 简单的介绍一下自己的工作经历与职责,在校或者工作中主要的工作内容,主要负责的内容;(你的信息一清二白的写在简历上,这个主要为了缓解面试者的压力) 介绍下自己最满意的,有技术亮点的项目或平台,重点介绍下自己负责那部分的技术细节;(主要考察应聘者对自己做过的事情是否有清晰的描述,判断做的事情的复杂度) 二、Java多线程相关 线程池的原理,为什么要创建线程池?创建线程池的方式; 线程的生命周期,什么时候会出现僵死进程; 说说线程安全问题,什么实现线...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Linux系统CentOS6、CentOS7手动修改IP地址
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS关闭SELinux安全模块
- CentOS8安装Docker,最新的服务器搭配容器使用
- 设置Eclipse缩进为4个空格,增强代码规范