zoukankan      html  css  js  c++  java
  • 谜题69 : 黑色的渐隐

    假设你不能修改前一个谜题(谜题 68)中的 X 和 C 这两个类。你能否编写一个类,其 main
    方法将读取 X.Y 类中的 Z 域的值,然后打印它。注意,不能使用反射。
    本谜题初看起来是不可能实现的。毕竟,X.Y 类被具有相同名字的一个域给遮掩
    了,因此对其命名的尝试将引用到该域上。
    事实上,我们是可以引用到一个被遮掩的类型名的,其技巧就是在某一种特殊的
    语法上下文环境中使用该名字,在该语法上下文环境中允许出现一个类型但是不
    允许出现一个变量。在转型表达式的括号中间的部分就是这样一种上下文环境。
    下面的程序通过使用这种技术解决了这个谜题,并且将打印出我们所期望的
    Black:

    public class FadeToBlack {
    public static void main(String[] args){
    System.out.println(((X.Y)null).Z);
    }
    }
    

      


    请注意,我们是用一个具有 X.Y 类型的表达式来访问 X.Y 类的 Z 域的。就像我们
    在谜题 48 和 54 中所看到的,用一个表达式而不是类型名来访问一个静态成员是
    合法的,但却是一种有问题的用法。

    不借助这种有问题的用法,而是通过在一个类声明的 extends 子句中使用一个被
    遮掩的类这种方式,你也可以解决本谜题。因为基类总是一种类型,出现在
    extends 子句中的名字从来都不会被解析为变量名。下面的程序就展示了这项技
    术,它也会打印出 Black:

    public class FadeToBlack {
    static class Xy extends X.Y{ }
    public static void main(String[ ] args){
    System.out.println(Xy.Z);
    }
    }
    

      


    如果你使用的 5.0 或更新的版本,那么通过在一个类型变量声明的 extends 子句
    中使用 X.Y 这种方式,你也可以解决本谜题:

    public class FadeToBlack {
    public static <T extends X.Y> void main(String[] args){
    System.out.println(T.Z);
    }
    }
    

      


    总之,要解决由类型被变量遮掩而引发的问题,需要按照标准的命名习惯来重命
    名类型和变量,就像在谜题 68 中所讨论的那样。如果做不到这一点,那么你应
    该在只允许类型名的上下文环境中使用被遮掩的类型名。幸运的话,你将永远不
    需要凭借这种对程序的变形来解决问题,因为大多数的类库作者都很明智,他们
    都避免了必需使用这种变形的有问题的用法。然而,如果你确实发现自己身处这
    种境地,那么你最好是要了解这个问题需要解决。

  • 相关阅读:
    Java Web学习总结(16)——JSP的九个内置对象
    Java Web学习总结(15)——JSP指令
    【我的物联网成长记11】8招带你玩转规则引擎
    云图说|高效管理华为云SAP的“秘密武器”
    Python 中更优雅的日志记录方案
    有了它,Python编码再也不为字符集问题而发愁了!
    【鲲鹏来了】手把手教你创造一个属于自己的鲲鹏开发者环境
    解密昇腾AI处理器--DaVinci架构(计算单元)
    使用Keil5构建GD32450i-EVAL工程
    云图说|SAP技术画册“一点通”
  • 原文地址:https://www.cnblogs.com/yuyu666/p/9841014.html
Copyright © 2011-2022 走看看