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

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. Windows 对全屏应用的优化

    全屏应用对应的是窗口模式应用,全屏应用指的是整个屏幕都是被咱一个应用独占了,屏幕上没有显示其他的应用,此时的应用就叫全屏应用.如希沃白板这个程序.本文主要告诉大家从微软官方的文档以及考古了解到的 Wi ...

  2. Go语言基础(一)

    一.Go语言简介 Go即Golang,是Google公司2009年11月正式对外公开的一门语言 Go是静态强类型语言,是区别于解析型语言的编译型语言. 解析型语言--源代码是先翻译为中间代码,然后解析 ...

  3. MDK在头文件中使用预编译器时,#ifdef 无效的问题

    问题:在头文件中使用预编译时,会出现无效的现象 在a.h文件中定义了宏AA_TEST,如下所示 #ifndef __A_H #define __A_H #define AA_TEST #endif 在 ...

  4. 【Nano Framework ESP32篇】使用 LCD 屏幕

    在开始主题之前,先介绍一个刷固件工具.这个工具在 idf 中是集成的,不过,乐鑫也单独发布了这个工具-- esptool.下载链接:Releases · espressif/esptool · Git ...

  5. CF746 期望+逆序对

    Link 题意:给定一个 \(1\) 到 \(n\) 的排列,等概率选一段区间 \([l, r]\) 随机排序,求期望逆序对数. \[E = \dfrac{\sum(cnt_{[1, n]} - cn ...

  6. STM32F1和STM32F4系列DMA的不同之处——对STM32的DMA的工作机制的一些理解

    喜欢用STM32的DMA功能.一方面STM32的DMA和MPU的DMA一样,可以提高数据传输效率.另一方面,作为一种MCU上的DMA,它可以提高针对外设(peripheral)的数据传输的实时性,改变 ...

  7. ansible系列(28)--ansible的playbook异常处理

    目录 1. playbook的异常处理 1.1 Playbook错误忽略 1.2 task执行失败强制调用handlers 1.3 控制Tasks报告状态为OK 1.4 changed_when检查任 ...

  8. SpringBoot-EasyExcel导出数据(带图片)

    前言 EasyExcel 是阿里巴巴开源的一个Java操作Excel的技术,和EasyPoi一样是封装Poi的工具类. 但是不同的地方在于,在EasyExcel中解决了Poi技术读取大批量数据耗费内存 ...

  9. 如何提高WordPress的加载速度

    针对wordpress加载速度慢的原因: 1. 由于Wordpress系统默认使用谷歌字体,在国内谷歌域名被屏蔽,所以导致操作反应慢.对于很多商业主题默认使用了谷歌字体.谷歌ajax库.谷歌地图等谷歌 ...

  10. JDK源码阅读-------自学笔记(二十)(java.util.List初探)

    List简介 List是有序.可重复的容器. 有序:List中每个元素都有索引标记.可以根据元素的索引标记(在List中的位置)访问元素,从而精确控制这些元素. 可重复:List允许加入重复的元素.更 ...