java谜题--java运行时修改引用类的静态常量

永磁同步电机控制笔记:foc控制原理通俗讲义 引言 到此为止,永磁同步电机控制相关文章已经写了7篇,其中simulink仿真系列文章5篇,控制笔记系列文章2篇,恍惚间感觉少了一篇概论,在此插入一篇,也算是对入坑电机控制一年半来的知识梳理。 文章目录引言一、同步电机是怎么转起来的二、什么样的旋转磁场效率最高三、怎么精准控制旋转磁场的方向四、怎样调节dq轴电流 一、同步电机是怎么转起来的 永磁同步电机结构如下: 外围是定子绕组,中间为永磁体,设... 阅读详情

谜题93:类的战争

下面这个谜题测试了你关于二进制兼容性(binary compatibility)的知识:当你改变了某个类所依赖的另外一个类时,第一个类的行为会发生什么改变呢?更特殊的是,假设你编译的是如下的2个类。第一个作为一个客户端,第二个作为一个库类,会怎么样呢:
public class PrintWords {
    public static void main(String[] args) {
        System.out.println(Words.FIRST  + " " + 
                           Words.SECOND + " " +
                           Words.THIRD);
    }
}

public class Words {
    private Words() { };  // Uninstantiable

    public static final String FIRST  = "the";
    public static final String SECOND = null;
    public static final String THIRD  = "set";
} 

现在假设你像下面这样改变了那个库类并且重编译了这个类,但并不重编译客户端的程序:

public class Words {
    private Words() { };  // Uninstantiable

    public static final String FIRST  = "physics";
    public static final String SECOND = "chemistry";
    public static final String THIRD  = "biology";
}

此时,客户端的程序会打印出什么呢?

简单地看看程序,你会觉得它应该打印 physics chemistry biology;毕竟Java是在运行期对类进行装载的,所以它总是会访问到最新版本的类。但是更深入一点的分析会得出不同的结论。对于常量域的引用会在编译期被转化为它们所表示的常量的值[JLS 13.1]。这样的域从技术上讲,被称作常量变量(constant variables),这可能在修辞上显得有点矛盾。一个常量变量的定义是:一个在编译期被常量表达式初始化的final的原始类型或String类型的变量[JLS 4.12.4]。在知道了这些知识之后,我们有理由认为客户端程序会将初始值Words.FIRST, Words.SECOND, Words.THIRD编译进class文件,然后无论Words类是否被改变,客户端都会打印the null set。

这种分析可能是有道理的,但是却是不对的。如果你运行了程序,你会发现它打印的是the chemistry set。这看起来确实太奇怪的了。它为什么会做出这种事情呢?答案可以在编译期常量表达式(compile-time constant expression)[JLS 15.28]的精确定义中找到。它的定义太长了,就不在这里写出来了,但是理解这个程序的行为的关键是null不是一个编译期常量表达式。

由于常量域将会编译进客户端,API的设计者在设计一个常量域之前应该深思熟虑。如果一个域表示的是一个真实的常量,例如π或者一周之内的天数,那么将这个域设为常量域没有任何坏处。但是如果你想让客户端程序感知并适应这个域的变化,那么就不能让这个域成为一个常量。有一个简单的方法可以做到这一点:如果你使用了一个非常量的表达式去初始化一个域,甚至是一个final域,那么这个域就不是一个常量。你可以通过将一个常量表达式传给一个方法使得它变成一个非常量,该方法将直接返回其输入参数。

如果我们使用这种方法来修改Word类,在Words类被重新修改和编译之后,PrintWords类将打印出physics chemistry biology:

public class Words {
private Words() {};  // Uninstantiable

    public static final String FIRST   = ident("the");
    public static final String SECOND  = ident(null);
    public static final String THIRD   = ident("set");

    private static String ident(String s) {
        return s;
    }
} 

在5.0版本中引入的枚举常量(enum constants),虽然有这样一个名字,但是它们并不是常量变量。你可以在枚举类型中加入枚举常量,对它们重新排序,甚至可以移除没有用的枚举常量,而且并不需要重新编译客户端。

总之,常量变量将会被编译进那些引用它们的类中。一个常量变量就是任何被常量表达式初始化的原始类型或字符串变量。令人惊讶的是,null不是一个常量表达式。

对于语言设计者来说,在一个动态链接的语言中,将常量表达式编译进客户端可能并不是一个好主意。这让很多程序员大吃一惊,并且很容易产生一些难以查出的缺陷:当缺陷被侦测出来的时候,那些定义常量的源代码可能已经不存在了。另外一方面,将常量表达式编译进客户端使得我们可以使用if语句来模拟条件编译(conditional compilation)[JLS 14.21]。为了正当目的可以不择手段的做法是需要每个人自己来判断的。 

常见消息队列:ActiveMQ、RabbitMQ、RocketMQ、Kafka的区别总结 常见消息队列:ActiveMQ、RabbitMQ、RocketMQ、Kafka的区别。 阅读详情

相关推荐

通讯软件002——快速使用modscan进行modbus调试

快速使用modscan进行modbus调试

zhouwl72的博客 1031

JAVA修改静态常量的方法

RT,代码块,一目了然   /* 以下省略xxx自定义方法名&参数&返回值的代码 ... */ //通过打开Field权限来实现静态常量的值 Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); //这里的f...

iteye_19353的博客 1847

手把手教你用NE555+LM324搭建红外倒车雷达(附Multisim仿真文件)

本文详细介绍了如何使用NE555定时器和LM324运算放大器搭建一个红外倒车雷达系统。内容涵盖从核心原理拆解、模块电路设计(包括红外发射、接收放大、检波与电压比较)到实战焊接调试的全过程,并提供了Multisim仿真验证思路,帮助电子爱好者与初学者将模拟电路理论转化为可工作的实用项目。

echo99的专栏 676

Java常量类,在修改静态常量的值之后,不生效

修改一个常量类中的静态常量值,然后把常量类的class文件上传到服务器后并没有生效,多次重启服务,最后查询了相关资料,使用GUI反编译工具反编译查看编译后源码,终于找到问题所在: 单纯的修改静态常量是没用的,还要重新编译所有引用静态变量的类(或把这些类重新上传服务器),不然不会生效。 这里就牵扯到Java虚拟机编译机制:在Java文件中,指向编译时static final的静态常量, 会在运行......

weixin_42046751的博客 4089

Win11专业版破解RDP限制:实现多用户远程桌面协同办公

本文详细介绍了如何在Windows 11专业版上破解RDP限制,实现多用户远程桌面协同办公。通过使用RDPWrap工具,用户可以绕过微软的授权限制,允许多个用户同时登录同一台电脑,提高硬件利用率和团队协作效率。文章包含详细的安装配置步骤、性能优化技巧及常见问题解决方案,适用于需要远程协作的办公场景。

weixin_33806300的博客 466

数电发票“乐企直连”服务平台建设方案

数字化电子发票“乐企直连”服务平台建设方案

m0_73174802的博客 4851

java修改static final String常量值

在项目中使用的JPA,`@Table`设置实体类表名,使用mysql数据库的话,设置`@Table`中`catalog`和`schema`可以在生成查询sql时,加上schema。例如表为`sys_node`,库名叫`stu_manage`,设置`schema=stu_manage`和`catalog=stu_manage`,sql就会变为`select * from stu_manage.sys_node ` 项目现在要访问另一个库的表,但是这个库schema不是固定的要从配置文件中读取。

我乃世间蓬蒿人 829

基于Meteoinfo与TrajStat的后向轨迹聚类分析实战:从数据准备到可视化制图

本文详细介绍了基于Meteoinfo与TrajStat进行后向轨迹聚类分析的完整实战流程。从Java环境配置、Meteoinfo软件与TrajStat插件安装,到精准获取NOAA气象数据、设置参数进行批量轨迹计算,再到利用聚类分析提炼主要气流路径,并最终完成专业地图可视化与制图。文章旨在帮助环境与气象研究者快速掌握从数据准备到成果输出的全链路操作。

p4q5r6s7t的博客 804

Java引用类型与常量

Java引用类型与常量           引用数据类型           Java中,引用类型的变量非常类似于C/C++的指针。           引用类型指向一个对象,指向对象的变量是引用变量,这些变量在声明时被指定为一个特定的类型,比如Employee、Pubby等,变量一旦声明后,类型就不能被改变了。           对象、数组都是引用数据类型。

天高任鸟飞 2645

015、架构_配置文件_管理节点(proxymanager.ini)

该配置文件中的参数在后台配置,两种生效方式:*所有参数重启生效。*部分参数可以使用工具dbtool动态生效。动态生效命令为:dbtool-pm-load-config。配置文件“proxymanager.ini”用于设置元数据管理模块的信息。文件路径为“~/etc”。配置文件“proxymanager.ini”是普通的文本文件。默认值proxymanager-alarmconfutf8.txt。配置错误或不配置,PM无法连接MDS,无法服务。获取元数据失败超时处理时间。异常时请求启动对等回滚。

Oracle/MySQL 到 国产信创数据库|迁移 · 调优 · 信创替换 328

华为流程L1-L6业务流程深度细化到可执行【附全文阅读】

该文档主要介绍了华为业务流程的深度细化及相关内容,包括流程框架、建模方法、流程模块描述、流程图建模等,旨在帮助企业构建有效的流程体系,实现战略目标。

cdfunlove的博客 4003

《java解惑》读书笔记6——类谜题

1.方法重载: 问题: 下面的程序演示方法重载,代码如下: public class Test{ public static void main(String[] args) { new Test(null); } private Test(Object o){ System.out.println("Object");

Tony Chen的专栏 3368

uniapp:实现扫描二维码+自定义扫描框+扫一扫功能,支持扫码识别二维码、条形码(条码)、微信/支付宝等二维码功能,自定义扫码页面可添加按钮或文字展示布局(移动端H5网页/小程序/安卓苹果APP端)

UNI-APP实现扫描二维码,uniapp扫描条形码,uniapp实现扫一扫功能,扫码成功后跳转页面,uniApp扫描条码,uniApp-H5 使用摄像头扫码功能(扫一扫),实现手机扫描二维码并跳转全过程示例代码,用户扫码后自动跳转到链接,uniapp怎么调用扫一扫功能,uniapp实现扫一扫功能,uniapp请求相机使用权限,扫一扫权限申请,uniapp调用摄像头扫码,uniapp实现调用相机扫码,UniApp 实现扫描二维码,uniapp APP安卓苹果ios实现扫码扫一扫,Uniapp微信小程序扫描二

✅ 精选推荐文章 4708

类谜题:关于静态域的一个小问题

知识点:静态与只有一个,没有拷贝,是共享的。 第二个:关于使用集成还是组合。 下面的程序使用了一个Counter类来跟踪每一种家庭宠物叫唤的次数。那么该程序会打印出什么呢? class Counter { private static int count = 0; public static final synchronized void increment() {

jiqikewang的专栏 642

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

《Java Puzzlers》——高级谜题

文章目录有毒的括号等价的自反性、传递性和对称性原生类型泛型序列化问题匿名内部类的继承常量表达式随机shuffle的公平性最终章,一些小知识 有毒的括号 问题:给定一个合法的 Java 表达式,添加一个注解赋值顺序的括号就变成不合法的了。 解决方案:补码的不对称性,给最小负数加一个括号就不合法了。 等价的自反性、传递性和对称性 不符合自反性,例如 Double.NaN == Double.NaN 为 false; 符合对称性; 不符合传递性,由于整数与浮点数之间的转换有可能会出现丢失精度的问题,所以可能破坏

编程碎碎念 340

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Java谜题畅读版之更多的类谜题

谜题66:一件私事 在下面的程序中,子类的一个域具有与超类的一个域相同的名字。那么,这个程序会打印出什么呢? class Base { public String className = "Base"; } class Derived extends Base { private String className = "Derived"; } public class Priva...

dawuafang 160

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

《java解惑》——类谜题

1.方法重载: 问题: 下面的程序演示方法重载,代码如下: [java] view plaincopy public class Test{              public static void main(String[] args) {           new Test(null);       }     

我只是一个简单的Coder,为了兴趣和理想奋斗在生活的道路上 628

java设计狗叫和狗咬_Java类谜题47:啊呀!我的猫变成狗了

面的程序使用了一个Counter类来跟踪每一种家庭宠物叫唤的次数。那么该程序会打印出什么呢?class Counter {private static int count = 0;public static final synchronized void increment() {count++;}public static final synchronized int getCount() {r...

weixin_42297705的博客 372

Java类中各种静态变量的加载顺序的学习

最近在补《thinking in java》...有一节提到了加载类需要做的一些准备...我照着书本敲了一下代码...同时稍微修改了一下书本上的代码.... 1 package charpter14; 2 3 import java.util.Random; 4 5 6 class Initable{ 7 static{ 8 ...

ajunkui4460的博客 117

谜题69 : 黑色的渐隐

假设你不能修改前一个谜题(谜题 68)中的 X 和 C 这两个类。你能否编写一个类,其 main方法将读取 X.Y 类中的 Z 域的值,然后打印它。注意,不能使用反射。本谜题初看起来是不可能实现的。毕竟,X.Y 类被具有相同名字的一个域给遮掩了,因此对其命名的尝试将引用到该域上。事实上,我们是可以引用到一个被遮掩的类型名的,其技巧就是在某一种特殊的语法上下文环境中使用该名字,在该语法上下文环境中允...

weixin_30562507的博客 73

谜题89:泛型迷药

和前一个谜题一样,本谜题也大量使用了泛型。我们从前面的错误中吸取教训,这次不再使用原生类型了。这个程序实现了一个简单的链表数据结构。main程序构建了一个包含2个元素的list,然后输出它的内容。那么,这个程序会打印出什么呢? public class LinkedList<E> { private Node<E> head = null; ...

weixin_30314793的博客 136

谜题38:不受欢迎的宾客

本谜题中的程序所建模的系统,将尝试着从其环境中读取一个用户ID,如果这种尝试失败了,则缺省地认为它是一个来宾用户。该程序的作者将面对有一个静态域的初始化表达式可能会抛出异常的情况。因为Java不允许静态初始化操作抛出被检查异常,所以初始化必须包装在try-finally语句块中。那么,下面的程序会打印出什么呢? public class UnwelcomeGuest { pub...

weixin_30918415的博客 76

码界奇缘 Java 觉醒 后记 第十五章 Project Leyden - 静态宇宙的永恒牢笼

注解(冰晶浮现新的纹路),在编译期生成所有可能的代理类——哪怕这会让镜像体积膨胀百倍!“在此宇宙,时间只有两态:编译时(展示冰封的代码瀑布)与运行时(瞬移光束)。正是隐藏恶意代码的最佳外衣…在静态宇宙运行被禁止的动态代码。“那接口代理如何实现?

weixin_43236925的博客 473

谜题43:异常地危险

在JDK1.2中,Thread.stop、Thread.suspend以及其他许多线程相关的方法都因为它们不安全而不推荐使用了[ThreadStop]。下面的方法展示了你用Thread.stop可以实现的可怕事情之一。 // Don’t do this - circumvents exception checking! public static void sneakyThrow(Th...

weixin_30471065的博客 114
上一篇: java谜题--类初始化时容易死锁情况
下一篇: Class.getResource vs ClassLoader.getResource
feiyu8607
博客等级 码龄18年 26粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值