• public final static PrintStream out = null; 的实例化猜想


    Java的控制台输出  System.out.println 以效率慢,调用简便闻名,但是在源码中out被static final 修饰,怎么把这个对象赋值呢?

    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();
        }

    意思是说该native是要让vm   'invoke '  调用  initializeSystemClass 方法   java里的invoke 懂得都懂

     /**
         * Initialize the system class.  Called after thread initialization.
         */
        private static void initializeSystemClass() {
    
            // VM might invoke JNU_NewStringPlatform() to set those encoding
            // sensitive properties (user.home, user.name, boot.class.path, etc.)
            // during "props" initialization, in which it may need access, via
            // System.getProperty(), to the related system encoding property that
            // have been initialized (put into "props") at early stage of the
            // initialization. So make sure the "props" is available at the
            // very beginning of the initialization and all system properties to
            // be put into it directly.
            props = new Properties();
            initProperties(props);  // initialized by the VM
    
            // There are certain system configurations that may be controlled by
            // VM options such as the maximum amount of direct memory and
            // Integer cache size used to support the object identity semantics
            // of autoboxing.  Typically, the library will obtain these values
            // from the properties set by the VM.  If the properties are for
            // internal implementation use only, these properties should be
            // removed from the system properties.
            //
            // See java.lang.Integer.IntegerCache and the
            // sun.misc.VM.saveAndRemoveProperties method for example.
            //
            // Save a private copy of the system properties object that
            // can only be accessed by the internal implementation.  Remove
            // certain system properties that are not intended for public access.
            sun.misc.VM.saveAndRemoveProperties(props);
    
    
            lineSeparator = props.getProperty("line.separator");
            sun.misc.Version.init();
    
            FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
            FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
            FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
            setIn0(new BufferedInputStream(fdIn));
            setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
            setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
    
            // Load the zip library now in order to keep java.util.zip.ZipFile
            // from trying to use itself to load this library later.
            loadLibrary("zip");
    
            // Setup Java signal handlers for HUP, TERM, and INT (where available).
            Terminator.setup();
    
            // Initialize any miscellenous operating system settings that need to be
            // set for the class libraries. Currently this is no-op everywhere except
            // for Windows where the process-wide error mode is set before the java.io
            // classes are used.
            sun.misc.VM.initializeOSEnvironment();
    
            // The main thread is not added to its thread group in the same
            // way as other threads; we must do it ourselves here.
            Thread current = Thread.currentThread();
            current.getThreadGroup().add(current);
    
            // register shared secrets
            setJavaLangAccess();
    
            // Subsystems that are invoked during initialization can invoke
            // sun.misc.VM.isBooted() in order to avoid doing things that should
            // wait until the application class loader has been set up.
            // IMPORTANT: Ensure that this remains the last initialization action!
            sun.misc.VM.booted();
        }

    引用知乎大佬的一段关于反射修改final的解释

    作者:Accelerator
    链接:https://www.zhihu.com/question/47054187/answer/127690274
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    泻药被final修饰过的变量,只是说栈存储的地址不能再改变,但是却没有说地址指向的内容不能改变,所以反射可以破final,因为它修改该了以前地址的具体内容,但是没有改地址的信息。
    举个例子:一个路段,只允许牌子为10000的车过,但是并没有说不允许套牌。牌子还是10000但是车变了。然后被static修饰的变量也能修改,
    同样道理,只不过第一个参数为null。但是同时被final和static变量修饰的就不能被修改了,会抛出异常,在jdk的doc(Field (Java Platform SE
    7 )中有描述至于能不能修改
    ,肯定能,因为@唐小狸已经给出了答案。
    field = Comtest.class.getDeclaredField("value1"); field.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field,field.getModifiers()&~Modifier.FINAL); field.set(null, new char[]{'1', '2', '3'}); field.getModifiers()&~Modifier.FINAL 这句话就是去掉final。其实java的访问权限信息啥的都是以2的N次幂来作为表示的,具体都是在java.lang.reflect.Modifier这个类里。
    getModifiers()&~Modifier.FINAL 具体看下问运算,如果有(111111&000000=000000.)抹去了16这个final标识。不行了,我大人叫我去吃饭了,,闪了////////////

    我的猜想就是虚拟机明面上用了native方法,但是实现逻辑上应该是类似反射修改变量之类的

  • 相关阅读:
    作业1-四则运算题目生成程序
    实验四 决策树算法及应用
    实验三朴素贝叶斯算法及应用
    自定义博客园背景
    机器学习 实验二 K-近邻算法及应用
    机器学习 实验一 感知器及其运用
    实验三 面向对象分析与设计
    实验二 结构化分析与设计
    实验一:软件开发文档与工具的安装与使用
    朴素贝叶斯学习日志——简单案例python计算过程
  • 原文地址:https://www.cnblogs.com/funkboy/p/13426710.html
Copyright © 2020-2023  润新知