Java基础-基础语法-native方法

Java工程师知识树 / Java基础

概念

native是一个计算机函数,一个Native Method就是一个Java调用非Java代码的接口。方法的实现由非Java语言实现,比如C或C++。

JDK中如何运行native方法

首先举个例子看一下在JDK中如何运行native方法的

    1. java源码中的native方法是不能直接在jdk中看到的,因为jdk不是开源的,要看到的话需要sun授权才行,现在只有openjdk是被sun公司授权,所以要查看的话,下载完整的OpenJDK源码包
    1. 下载或查看完整的OpenJDK源码
      官网:OpenJDK
      image.png
      image.png
      image.png
      image.png
    1. 找一个JDK中使用native方法的实例
TimeZone.getDefault();//Java读取默认时区  java.util.TimeZone

class文件中的源码为

  public static TimeZone getDefault() {
      return (TimeZone) getDefaultRef().clone();// 第一步
  }
 ...
static TimeZone getDefaultRef() {
        TimeZone defaultZone = defaultTimeZone;
        if (defaultZone == null) {
            // Need to initialize the default time zone.
            defaultZone = setDefaultZone();// 如果没有设置时区的话 第二步
            assert defaultZone != null;
        }
        // Don't clone here.
        return defaultZone;
    }

    private static synchronized TimeZone setDefaultZone() {
        TimeZone tz;
        // get the time zone ID from the system properties
        String zoneID = AccessController.doPrivileged(
                new GetPropertyAction("user.timezone"));

        // if the time zone ID is not set (yet), perform the
        // platform to Java time zone ID mapping.
        if (zoneID == null || zoneID.isEmpty()) {
            String javaHome = AccessController.doPrivileged(
                    new GetPropertyAction("java.home"));
            try {
                zoneID = getSystemTimeZoneID(javaHome);// 如果没有设置时区的话 第三步
                if (zoneID == null) {
                    zoneID = GMT_ID;
                }
            } catch (NullPointerException e) {
                zoneID = GMT_ID;
            }
        }

        // Get the time zone for zoneID. But not fall back to
        // "GMT" here.
        tz = getTimeZone(zoneID, false);

        if (tz == null) {
            // If the given zone ID is unknown in Java, try to
            // get the GMT-offset-based time zone ID,
            // a.k.a. custom time zone ID (e.g., "GMT-08:00").
            String gmtOffsetID = getSystemGMTOffsetID();
            if (gmtOffsetID != null) {
                zoneID = gmtOffsetID;
            }
            tz = getTimeZone(zoneID, true);
        }
        assert tz != null;

        final String id = zoneID;
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            @Override
                public Void run() {
                    System.setProperty("user.timezone", id);
                    return null;
                }
            });

        defaultTimeZone = tz;
        return tz;
    }
...
    /**
     * Gets the platform defined TimeZone ID.
     **/
    private static native String getSystemTimeZoneID(String javaHome);

第三步中调用的getSystemTimeZoneID(String javaHome)这个方法就是native方法.

-4. 通过OpenJDK查看下getSystemTimeZoneID这个方法是什么

jdk.png
share 平台无关的共通代码.png
image.png

然后根据java.util.TimeZone的路径找到对应的native包下的信息
image.png
image.png

在java层面我们仅仅须要dll文件,.c文件的目的仅仅是为了生成dll文件.
这个时候回头看下整个流程:

  • 执行TimeZone.getDefault();
  • JVM加载TimeZone字节码到内存,同时因为getSystemTimeZoneID(String javaHome)方法描述符内有native,这个描述符块将有一个指向该方法的实现的指针;
  • src/share/native/java/util/TimeZone.c文件编译后生成DLL文件,而方法的实现就在这个DLL文件中;
  • 在执行getSystemTimeZoneID(String javaHome)方法的同时DLL文件会被操作系统加载到java程序的地址空间;
  • JVM完成对Java外的环境交互.

总结:

JVM如何运行Native方法

一个类第一次被使用到时,这个类的字节码会被加载到内存,并且只会加载一次。在这个被加载的字节码的入口维持着一个该类所有方法描述符的list,这些方法描述符包含这样一些信息:方法代码存于何处,它有哪些参数,方法的描述符(public之类)等等。

如果一个方法描述符内有native,这个描述符块将有一个指向该方法的实现的指针;这些实现在一些DLL文件内,但是它们会被操作系统加载到java程序的地址空间;
当一个带有本地方法的类被加载时,其相关的DLL并未被加载,因此指向方法实现的指针并不会被设置。当本地方法被调用之前,这些DLL才会被加载,这是通过调用java.system.loadLibrary()实现的。

为什么需要Native方法呢

  • 有些功能Java实现不易.比如读取默认时区,使用Java实现是不太容易的.
  • 使用C语言或者C++等其他语言执行效率会更高
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hughjin

动力动力动力动力动力动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值