首页 > 编程语言 >《Java编程思想》读书笔记(四)

《Java编程思想》读书笔记(四)

时间:2022-09-04 16:01:42浏览次数:76  
标签:编程 Java enum 读书笔记 Enum System Explore println out

前言:三年之前就买了《Java编程思想》这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第十七章到第十八章的内容,这一次记录的是第十九章到第二十章的内容,相关示例代码放在码云上了,码云地址:https://gitee.com/reminis_com/thinking-in-java

 

package enumerated;

/**
 * @author Mr.Sun
 * @date 2022年09月02日 15:58
 *
 * 枚举的基本特性
 */
public class EnumClass {
    public static void main(String[] args) {
        for(Shrubbery s : Shrubbery.values()) {
            System.out.println(s + " ordinal: " + s.ordinal());
            System.out.print(s.compareTo(Shrubbery.CRAWLING) + " ");
            System.out.print(s.equals(Shrubbery.CRAWLING) + " ");
            System.out.println(s == Shrubbery.CRAWLING);
            System.out.println(s.getDeclaringClass());
            System.out.println(s.name());
            System.out.println("----------------------");
        }

        // 从字符串名称生成枚举值
        for(String s : "HANGING CRAWLING GROUND".split(" ")) {
            Shrubbery shrub = Enum.valueOf(Shrubbery.class, s);
            System.out.println(shrub);
        }
    }
}

enum Shrubbery {
    GROUND, CRAWLING, HANGING
}

 

 

运行结果如下图:

ordinal()方法返回一个int值,这是每个enum实例在声明时的次序,从0开始。可以使用==来比较enum实例,编译器会自动为你提供equals()和hashCode()方法。Enum类实现了Comparable 接口,所以它具有compareTo()方法。同时,它还实现了Serializable接口。
  如果在enum实例上调用getDeclaringClass()方法,我们就能知道其所属的enum类。name()方法返回enum实例声明时的名字,这与使用toString()方法效果相同。valueOf()是在Enum中定义的static方法,它根据给定的名字返回相应的enum实例,如果不存在给定名字的实例,将会抛出异常。

values()的神秘之处

  前面已经提到,编译器为你创建的enum类都继承自Enum类。然而,如果你研究一下Enum 类就会发现,它并没有values()方法。可我们明明已经用过该方法了,难道存在某种“隐藏的”方法吗?我们可以利用反射机制编写一个简单的程序,来查看其中的究竟∶

package enumerated;

import utils.OSExecute;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Set;
import java.util.TreeSet;

/**
 * @author Mr.Sun
 * @date 2022年09月02日 16:10
 *
 * 使用反射机制研究枚举类的values()
 */
enum Explore {
    HERE, THERE
}

public class Reflection {

    public static Set<String> analyze(Class<?> enumClass) {
        System.out.println("----- Analyzing " + enumClass + " -----");
        System.out.println("Interfaces:");
        for (Type t : enumClass.getGenericInterfaces()) {
            System.out.println(t);
        }
        System.out.println("Base: " + enumClass.getSuperclass());
        System.out.println("Methods: ");
        Set<String> methods = new TreeSet<String>();
        for (Method method : enumClass.getMethods()) {
            methods.add(method.getName());
        }
        System.out.println(methods);
        return methods;
    }

    public static void main(String[] args) {
        Set<String> exploreMethods = analyze(Explore.class);
        Set<String> enumMethods = analyze(Enum.class);
        System.out.println("Explore.containsAll(Enum)? " + exploreMethods.containsAll(enumMethods));
        System.out.print("Explore.removeAll(Enum): ");
        exploreMethods.removeAll(enumMethods);
        System.out.println(exploreMethods);
        // Decompile the code for the enum:
        OSExecute.command("javap G:/github/cnblogs/gitee/thinking-in-java/out/production/thinking-in-java/enumerated/Explore.class");
    }

} /* Output:
----- Analyzing class enumerated.Explore -----
Interfaces:
Base: class java.lang.Enum
Methods: 
[compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, values, wait]
----- Analyzing class java.lang.Enum -----
Interfaces:
java.lang.Comparable<E>
interface java.io.Serializable
Base: class java.lang.Object
Methods: 
[compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, wait]
Explore.containsAll(Enum)? true
Explore.removeAll(Enum): [values]
Compiled from "Reflection.java"
final class enumerated.Explore extends java.lang.Enum<enumerated.Explore> {
  public static final enumerated.Explore HERE;
  public static final enumerated.Explore THERE;
  public static enumerated.Explore[] values();
  public static enumerated.Explore valueOf(java.lang.String);
  static {};
}
*///:~

 答案是,values()是由编译器添加的static方法。可以看出,在创建Explore的过程中,编译器还为其添加了valueOf()方法。这可能有点令人迷惑,Enum类不是已经有valueOf()方法了吗。不过Enum中的valueOf()方法需要两个参数,而这个新增的方法只需一个参数。由于这里使用的Set只存储方法的名字,而不考虑方法的签名,所以在调用Explore.removeAl(Enum)之后,就只剩下【values】了。
  从最后的输出中可以看到,编译器将Explore标记为final类,所以无法继承自enum。其中还有一个static的初始化子句,稍后我们将学习如何重定义该句。
  由于擦除效应(在第15章中介绍过),反编译无法得到Enum的完整信息,所以它展示的Explore的父类只是一个原始的Enum,而非事实上的Enum。
  由于values()方法是由编译器插入到enum定义中的static方法,所以,如果你将enum实例向上转型为Enum,那么values()方法就不可访问了。不过,在Class中有一个getEnumConstants()方法,所以即便Enum接口中没有values()方法,我们仍然可以通过Class对象取得所有enum实例∶

 

enum Search {
    HITHER, YON
}


public class UpcastEnum {
    public static void main(String[] args) {
        Search[] values = Search.values();
        for (Search val : values) {
            System.out.println(val.name());
        }
        System.out.println("--------------");
        Enum e = Search.HITHER;
        for (Enum en : e.getClass().getEnumConstants()) {
            System.out.println(en);
        }
    }
}

 

标签:编程,Java,enum,读书笔记,Enum,System,Explore,println,out
From: https://www.cnblogs.com/iyuyixyz/p/16655249.html

相关文章

  • Java流程控制
    01用户交互Scanner我们通过Scanner类获取用户的输入。基本语法:Scanners=newScanner(System.in);通过Scanner类的next()或nextLine()方法来获取输入的字符串,再读......
  • JavaDoc注释
    生成API文档时的参数信息@author作者名@version版本号@since最早可使用的jdk版本@param参数名@return返回值@throws抛出异常生成自己的API说明文档使用CMD方......
  • 教材第一章读书笔记
    教材第一章读书笔记by20201321周慧琳学习目标第一章:引言第一章的引言部分包涵Unix的历史、Linux的开发和各种版本(没有提及centOS和openeuler,我们可以自己补充学习),还......
  • 第十章-JavaScript 互操作性
    从C#调用JavaScript浏览器具有许多您可能希望在Blazor网站中使用的功能。例如,您可能希望使用浏览器的本地存储来跟踪某些数据。由于Blazor的JavaScript互操作性......
  • java学习笔记019 JDK 8新特性
    1.Lambda表达式eg1: //原始写法 Runnabler1=newRunnable(){ @Override publicvoidrun(){ System.out.println("helloworld"); } } r1.run(); //Lamb......
  • Java中Iterator和ListIterator用法整理
    1 迭代器简介(Iterator)迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建......
  • 10 个实用的 Python 编程技巧
    字典翻转首先我们来看字典的翻转,假设我们有下面类似的一个字典对象与数据car_dict={"brand":"Tesla","model":"ModelY","year":2017}倘若我们......
  • 使用DES算法的加解密Java工具类-字符串加解密
    importjavax.crypto.*;importjavax.crypto.spec.DESKeySpec;importjava.security.SecureRandom;importorg.apache.commons.codec.binary.Base64;/***@ClassN......
  • Java中计算两个时间相差多少天,时,分,秒
    importjava.text.ParseException;importjava.text.SimpleDateFormat;importjava.time.LocalDate;importjava.util.Date;StringstrTime1="2020-12-0412:20:2......
  • Java如何获取两个日期之间的月份和年份列表
    1、获取年份列表示例如下importjava.text.DateFormat;importjava.text.ParseException;importjava.text.SimpleDateFormat;importjava.util.Calendar;​public......