首页 > 编程语言 >从new File("")到jdk源码

从new File("")到jdk源码

时间:2022-08-25 01:11:26浏览次数:103  
标签:jdk System 绝对路径 获取 源码 File props new 方法

1. 概述

今天在项目中看到下面两行代码,看注释说是获取当前工作路径,之前也没有用过这种用法,比较好奇还能这样用,所以研究了一下源码。

//获取当前工作路径
File file = new File("");
String currentWorkDirectory = file.getAbsolutePath();

2. new File("")解析

首先,new File()是创建一个虚拟的文件(File)对象,通过这个对象可以调用很多方法来获取文件和目录的相关信息。以下列出一些常用方法:

2.1 File的常用方法

方法签名 作用
boolean delete() 删除文件或目录
void deleteOnExit() 在jvm退出时删除文件或目录
boolean createNewFile() 当以这个文件名命名的文件不存在时,创建一个新的空文件
boolean exists() 判断文件或目录是否存在
String getAbsolutePath() 获取File对象的绝对路径
String getName() 获取文件或目录名称
File getParentFile() 获取父File对象
String getPath() 获取File对象创建时传入的pathname参数
boolean isDirectory() 判断是否是目录
File[] listFiles() 列出当前目录下的所有文件
boolean mkdir() 创建单个目录
boolean mkdirs() 创建多级目录

2.2 new File("")做了什么

我们先来看看源码是怎么描述的:
image
其中注释的意思是:将指定的文件路径转换为一个绝对路径,然后创建一个新的File实例。如果给定的文件路径参数为空值,则返回空的绝对路径名。

官方的注释比较难理解,通俗的将就是,当我传入一个相对路径就会转换为绝对路径,当我传入一个""参数时,就只有一个绝对路径。那么这个绝对路径代表什么含义呢?

2.3 深入源码看File绝对路径(abstract pathname)的含义

2.3.1 File.getAbsolutePath()方法

其实我们可以看到new File(String pathname)这个构造方法只设置了相对路径和解析相对路径的长度。并没有有关绝对路径的操作。那么究竟是在哪里设置的绝对路径呢?这个就涉及到getAbsolutePath()方法了。

下面我们看一下getAbsolutePath()方法做了什么:
image
从注释可以看出,如果在new File()的时候传入的pathname已经是绝对路径的话,那么这个方法的返回就和getPath()一样,如果传入的是空字符串的话,那么就返回当前目录的路径,通过系统属性user.dir获取。

2.3.2 WinNTFileSystem.resolve()方法

那么我们继续往下看:
image

点进去resolve()方法可以看到返回值实际是从getUserPath()这个方法获取的。

image

2.3.3 WinNTFileSystem.getUserPath()方法

getUserPath()方法调用了System.getProperty("user.dir")方法来获取user.dir这个key的配置。再往里面看user.dir的值其实是从props这个Properties对象中获取的。

image

2.3.4 System.setProperties(props)方法

那props又是从哪里拿到这个值的呢?我们接着往下看:
在System类里面对着props这个属性用ctrl+鼠标左键查找props在哪几个地方使用了。可以看到有一个setProperties(Properties props)方法。再对着setProperties这个方法使用ctrl+鼠标左键查找。
image

2.3.5 Process.main()方法

在com.sun.org.apache.xalan.internal.xslt.Process的main方法里面我们可以看到,执行了System.setProperties(props),而System.setProperties(props)调用了本地方法private static native Properties initProperties(Properties props)对props进行初始化。

image

2.3.6 System.initProperties(Properties props)本地方法

image

到这里的话,其实java源代码已经结束了,总结来说就是jvm在启动的时候调用了System类的private static native Properties initProperties(Properties props)本地方法对props属性进行初始化,设置了user.dir的值。

这时可能还有些好奇宝宝不甘心,为什么调用了这个本地方法就可以获取user.dir的值,那么我们就来研究一下openjdk的c语言源码吧。

2.4 深入openjdk源码

我们从github上搜索到openjdk的源码仓库,随便找一个java8的tag来研究initProperties()这个本地方法到底做了什么。
github的openjdk代码仓库

  1. 首先我们找到jdk/src/share/native/java/lang目录下面的System.c文件。在里面搜索一下initProperties,可以看到有一个Java_java_lang_System_initProperties方法。
    image

  2. 接着我们在这个方法里面搜索user_dir,可以看到值是从一个sprops指针中获取的,而sprops从上一张图可以看出是从GetJavaProperties(env)这个方法获取的值。
    image

  3. 那我们ctrl+shift+F全局搜索一下GetJavaProperties这个方法。可以看到jdk/src/windows/native/java/lang/java_props_md.c文件中有这个方法,从文件路径可以看出这个文件是windows系统下执行的。
    image

  4. 接着在这个方法里面搜索user_dir,可以看到user_dir实际是从GetCurrentDirectoryW(sizeof(buf)/sizeof(WCHAR), buf)方法里面获取值的。GetCurrentDirectoryW这个方法就是windows的系统函数,用来获取当前工作目录。
    image

到这里jdk源码解析就结束了,可以看到在windows系统下是调用了它的系统函数获取当前工作目录。

备注:_wcsdup(buf)方法是c语言的库函数,作用是分配一块新的空间,然后从buf数组里面获取值赋值给新创建的空间。

3. 总结

  1. 绝对路径是什么:当前工作目录,就是当前项目的根路径
  2. 使用new File("")创建File对象时,绝对路径其实是getAbsolutePath()方法获取的,new File("")只是设置了path=""
  3. System.props这个属性其实包含了很多值,如:java.version、user.home等等,可以看源码中的注释
  4. 通过System.getProperty(key)可以获取系统的一些配置信息

标签:jdk,System,绝对路径,获取,源码,File,props,new,方法
From: https://www.cnblogs.com/yywf/p/16622889.html

相关文章

  • ForkJoinPool源码分析之三(ForkJoinTask源码)
    一、类结构及其成员变量1.1类结构和注释类前面的注释部分如下:ForkJoinTask是在ForkJoinPool中运行task的基础抽象类,ForkJoinTask是类似于线程的实体,其权重比普通线程要......
  • ForkJoinPool源码分析之四(ForkJoinWorkerThread源码)
    一、类结构及其成员变量1.1类结构和注释类结构代码如下:publicclassForkJoinWorkerThreadextendsThread{}ForkJoinWorkerThread继承了Thread类,ForkJoinWo......
  • 以太坊 layer2: optimism 源码学习(二) 提现原理
    作者:林冠宏/指尖下的幽灵。转载者,请:务必标明出处。掘金:https://juejin.im/user/1785262612681997博客:http://www.cnblogs.com/linguanh/GitHub:https://git......
  • 《Python源码剖析》PDF高清版试读
      《Python源码剖析》PDF高清版免费下载地址  内容简介  · · · · · ·作为主流的动态语言,Python不仅简单易学、移植性好,而且拥有强大丰富的库的......
  • Spring 源码学习笔记10——Spring AOP
    Spring源码学习笔记10——SpringAOP参考书籍《Spring技术内幕》SpringAOP的实现章节书有点老,但是里面一些概念还是总结比较到位源码基于Spring-aop5.3.22可能和旧......
  • LNMP架构的源码编译
    LNMP架构的源码编译一、LNMP架构的编译安装1.安装nginx服务(1)关闭防火墙[root@localhost~]#systemctlstopfirewalld[root@localhost~]#systemctldisablefirew......
  • 新字符设备驱动原理和框架源码分析
    一、分配和释放设备号动态申请设备号:/*dev:设备号--dev_tdevid;count:是要申请的数量,一般都是一个;name:是设备名字*/intalloc_chrdev_region(dev_t*dev,uns......
  • CBV源码剖析
    你自己不要修改源码除了bug很难找突破口在urls.pyurl(r'^login/',views.MyLogin.as_view())url(r'^login/',views.view)FBV一模一样CBV与FBV在路由匹配上本质是一样......
  • 即时通讯源码(基于websocket即时通讯源码uniapp)+视频搭建教程
    即时通讯系统源码服务器端构架目录:1、构建基本服务器2、用户在线功能3、用户消息广播机制4、用户业务层封装5、在线用户查询6、修改用户名......
  • 定制化JDK升级引发的离奇事件
    1、背景由于Oracle对外宣称OracleJDK停止免费用于商用。公司法务部门评估之后担心后续会惹上光司,于是就开始了JDK升级-将所有服务Oracle修改为OpenJDK。上周开始微服务JD......