最近有同事问我,以下这个语句是什么意思?

MqMessge<MqMessgeThink> mm= JSON.parseObject(message.toString(),new TypeReference<MqMessge<MqMessgeThink>>(){});

就是红色粗体部分是什么意思。

我说这是要创建一个匿名类的实例。

一、语法和用途

匿名类网上到处有详细的介绍,例如Java 匿名类 | 菜鸟教程 (runoob.com)

截个图,这个图中的内容非常贴切地说明了匿名类是什么,用于什么场景。

注意下定义匿名类的语法: new SuperClass(?){.....}

语法分为三个部分:

1.关键字:new

2.父类/接口的构造方法

3.{.....}:匿名类的实现体

这三个组合起来就是一个意思:新建一个匿名类继承/实现某个父类/接口,并创建这个匿名类的匿名对象。

注意,也可以为创建的对象命名,例如

SuperClass<T> x=new SuperClass<T>(){};

SuperClass x=new SuperClass(){};

SuperClass<T> x=new SuperClass<T>(){

   public void do(){

      System.out.println("落后就要挨打!");

   }

};

如果是为了实现实现接口,那么也可以看Java 匿名类 | 菜鸟教程 (runoob.com)的例子:

二、看具体例子

还是以new TypeReference<MqMessge<MqMessgeThink>>(){}为例子进行说明。

首先看下阿里TypeReference的定义:

public class TypeReference<T> {
static ConcurrentMap<Type, Type> classTypeCache
= new ConcurrentHashMap<Type, Type>(16, 0.75f, 1); protected final Type type; protected TypeReference(){
Type superClass = getClass().getGenericSuperclass(); Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; Type cachedType = classTypeCache.get(type);
if (cachedType == null) {
classTypeCache.putIfAbsent(type, type);
cachedType = classTypeCache.get(type);
} this.type = cachedType;
} /**
* @since 1.2.9
* @param actualTypeArguments
*/
protected TypeReference(Type... actualTypeArguments){
Class<?> thisClass = this.getClass();
Type superClass = thisClass.getGenericSuperclass(); ParameterizedType argType = (ParameterizedType) ((ParameterizedType) superClass).getActualTypeArguments()[0];
Type rawType = argType.getRawType();
Type[] argTypes = argType.getActualTypeArguments(); int actualIndex = 0;
for (int i = 0; i < argTypes.length; ++i) {
if (argTypes[i] instanceof TypeVariable &&
actualIndex < actualTypeArguments.length) {
argTypes[i] = actualTypeArguments[actualIndex++];
}
// fix for openjdk and android env
if (argTypes[i] instanceof GenericArrayType) {
argTypes[i] = TypeUtils.checkPrimitiveArray(
(GenericArrayType) argTypes[i]);
} // 如果有多层泛型且该泛型已经注明实现的情况下,判断该泛型下一层是否还有泛型
if(argTypes[i] instanceof ParameterizedType) {
argTypes[i] = handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex);
}
} Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType);
Type cachedType = classTypeCache.get(key);
if (cachedType == null) {
classTypeCache.putIfAbsent(key, key);
cachedType = classTypeCache.get(key);
} type = cachedType;
} public static Type intern(ParameterizedTypeImpl type) {
Type cachedType = classTypeCache.get(type);
if (cachedType == null) {
classTypeCache.putIfAbsent(type, type);
cachedType = classTypeCache.get(type);
} return cachedType;
} private Type handlerParameterizedType(ParameterizedType type, Type[] actualTypeArguments, int actualIndex) {
Class<?> thisClass = this.getClass();
Type rawType = type.getRawType();
Type[] argTypes = type.getActualTypeArguments(); for(int i = 0; i < argTypes.length; ++i) {
if (argTypes[i] instanceof TypeVariable && actualIndex < actualTypeArguments.length) {
argTypes[i] = actualTypeArguments[actualIndex++];
} // fix for openjdk and android env
if (argTypes[i] instanceof GenericArrayType) {
argTypes[i] = TypeUtils.checkPrimitiveArray(
(GenericArrayType) argTypes[i]);
} // 如果有多层泛型且该泛型已经注明实现的情况下,判断该泛型下一层是否还有泛型
if(argTypes[i] instanceof ParameterizedType) {
argTypes[i] = handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex);
}
} Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType);
return key;
} /**
* Gets underlying {@code Type} instance.
*/
public Type getType() {
return type;
} public final static Type LIST_STRING = new TypeReference<List<String>>() {}.getType();
}

注意,TypeReference的两个构造函数都是protected类型,这意味着在包外面是无法直接访问的。

所以,为了能够访问,只能继承类TypeReference,怎么继承? 用匿名类(因为只用了一次)。语法如前所记述。

三、小结

1.创建匿名类主要是为了创建对应的实例

2.用于继承无法直接创建的类(构造函数范围受限);实现接口

3.简化调用方式

4.适当减少工作量

5.让不注意基础的人迷糊

虽然匿名类从某个角度出发不是那么友好(例如学习和维护),但不妨碍性能和开发效率,所以还是非常好用的。

从另外一个角度出发,技巧性少一些,其实有时候更有利于学习和工程,但既然有了,既然已经学了,那么就用吧。

java基础-匿名类/对象的更多相关文章

  1. Java基础-IO流对象之字符类(FileWrite与FileReader)

    Java基础-IO流对象之字符类(FileWrite与FileReader) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.常见编码简介 1>ASCII 我们知道计算机是 ...

  2. Java基础-IO流对象之File类

    Java基础-IO流对象之File类 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.IO技术概述 回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下 ...

  3. Java基础 -- 嵌套类(非静态嵌套类、静态嵌套类)

    可以将一个类的定义放在另一个类的内部定义,这样的类就被称为嵌套类,包含嵌套类的类被称为外部类(outer class),也可以叫做封闭类. 嵌套类可以分为两种: 静态嵌套类(Static Nested ...

  4. 第二十九节:Java基础知识-类,多态,Object,数组和字符串

    前言 Java基础知识-类,多态,Object,数组和字符串,回顾,继承,类的多态性,多态,向上转型和向下转型,Object,数组,多维数组,字符串,字符串比较. 回顾 类的定义格式: [类的修饰符] ...

  5. Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream)

    Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.内存 ...

  6. Java基础-IO流对象之序列化(ObjectOutputStream)与反序列化(ObjectInputStream)

    Java基础-IO流对象之序列化(ObjectOutputStream)与反序列化(ObjectInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.对象的序 ...

  7. java基础-IO流对象之Properties集合

    java基础-IO流对象之Properties集合 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Properties集合的特点 Properties类表示了一个持久的属性集. ...

  8. Java基础-IO流对象之字节缓冲流(BufferedOutputStream与BufferedInputStream)

    Java基础-IO流对象之字节缓冲流(BufferedOutputStream与BufferedInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在我们学习字 ...

  9. Java基础-IO流对象之转换流(InputStreamReader与OutoutStreamWriter)

    Java基础-IO流对象之转换流(InputStreamReader与OutoutStreamWriter) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.转换流概述 我们之前 ...

  10. Java基础-IO流对象之字节流(Stream)

    Java基础-IO流对象之字节流(Stream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在前面我分享的笔记中,我们一直都是在操作文件或者文件夹,并没有给文件中写任何数据.现 ...

随机推荐

  1. WPF 引用 UWP 控件 不打包为 MSIX 分发的方法

    按照微软的官方文档,大部分的文档都会说如果用了 XAML Islands 等技术的时候,需要新建一个打包项目,将 WPF 应用打包为 msix 等才可以进行分发和使用.但是实际上不打包也可以,此时可以 ...

  2. k8s修改iptables模式变成ipvs

    环境:https://www.cnblogs.com/yangmeichong/p/16477200.html 一.修改 iptables 变成 ipvs 模式 ipvs 采用的 hash 表,ipt ...

  3. LVGL SCROLL循环滚动

    一.案例测试 这里我使用LVGL的版本是8.3.3 运行案例 lvgl_examples\scroll\lv_example_scroll_6 效果如下所示 二.现象 这里先描述一下现象,当我们使用 ...

  4. join分析:shuffle hash join、broadcast hash join

    Join 背景介绍 Join 是数据库查询永远绕不开的话题,传统查询 SQL 技术总体可以分为简单操作(过滤操作.排序操作 等),聚合操作-groupby 以及 Join 操作等.其中 Join 操作 ...

  5. Ubuntu-kali配置动态ip(简单)

    使用gedit文本编辑器打开网络接口配置文件 gedit /etc/network/interfaces 新增两行内容如下: auto eth0 iface eth0 inet dhcp 其意思为:网 ...

  6. centos7 hpc高性能计算集群配置(无密码访问、nfs文件共享)

    0.检查硬件的超线程 由于模型运行时,每个进程几乎都会占用100%的CPU计算能力,开启超线程之后,每个进程最多使用每个核心50%的计算能力,导致程序运行变慢. 1,物理CPU个数:cat /proc ...

  7. salesforce零基础学习(一百三十六)零碎知识点小总结(八)

    本篇参考: Salesforce LWC学习(七) Navigation & Toast https://developer.salesforce.com/docs/platform/lwc/ ...

  8. 带有声音/音频的 Mac 远程桌面

    一言以蔽之:如果你用远程桌面软件访问mac电脑遇到声音问题,改用Splashtop就好了.Splashtop对于Mac 的远程桌面支持非常棒. 尽管有几种远程桌面工具可提供对 Mac 的远程访问,但许 ...

  9. typora不支持mermaid 问题记录

    typora不支持mermaid 问题记录 注意: 使用不了最新版本js,目前我测的最高版本9.3,有些复杂的图表不能用,不过已经满足我使用的需求了.知足了 本文只做记录,如有问题请联系删除!!!感谢 ...

  10. Dapr 与 .NET Aspire 结合使用获得无与伦比的本地开发体验

    Dapr 提供了一组构建块,用于抽象分布式系统中常用的概念.这包括服务.缓存.工作流.复原能力.机密管理等之间的安全同步和异步通信.不必自己实现这些功能,可以消除样板,降低复杂性,并允许您专注于开发业 ...