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

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. OpenTK 入门 初始化窗口

    本文属于 OpenTK 入门博客,这是一项使用 C# 做底层调用 OpenGL 和 OpenAL 和 OpenCL 的技术.但值得一提的是,如果是想做渲染相关的话,当前是不建议使用 OpenGL 的, ...

  2. C# - 自建 SDK 的 API 文档

    在代码中添加 API 文档 用户在使用类库时,通常需要通过 VS 的 Intellisense 或 F12 反编译查看 API 的注释,借助这些注释来了解如何使用 API.在 C# 源文件中,可以通过 ...

  3. js的几个截取

    jsfun(){         let str = '01234567'         let str1         str1 = str.slice(2,5)                 ...

  4. Oracle、达梦:生成32位字符串(ID)

    15.生成32位字符串 达梦.oracle 函数:sys_guid().newid() 转小写LOWER(char) select rawtohex(sys_guid()); -- 推荐使用newid ...

  5. 美团二面:SpringBoot读取配置优先级顺序是什么?

    引言 Spring Boot作为一种轻量级的Java应用程序框架,以其开箱即用.快速搭建新项目的特性赢得了广大开发者的青睐.其核心理念之一就是简化配置过程,使开发者能够快速响应复杂多变的生产环境需求. ...

  6. 4G EPS 中的消息类型

    目录 文章目录 目录 消息 MIB(主消息块) SIBs(多个系统消息块) 系统消息的映射和调度 系统信息的更改通知 消息 LTE 的系统消息是蜂窝网络与 UE 互相交互的与 LTE 系统相关的.特殊 ...

  7. 4G EPS 第四代移动通信系统

    目录 文章目录 目录 4G EPS 4G EPS 4G(the 4th generation mobile communication technology,第四代移动通信技术)提供了 3G 不能满足 ...

  8. ajax跨域(跨源)方案之CORS

    ajax跨域(跨源)方案:后端授权[CORS],jsonp,服务端代理 CORS是一个W3C标准,全称是"跨域资源共享",它允许浏览器向跨源的后端服务器发出ajax请求,从而克服了 ...

  9. Flutter(六):Flutter_Boost接入现有原生工程(iOS+Android)

    本篇博客会介绍如何通过第三方插件Flutter_Boost实现接入原有工程. 如果不希望引入第三方插件,可以参考博客Flutter混合开发--接入现有原生工程(iOS+Android) 一.新建原生工 ...

  10. Python爬虫 | 批量爬取今日头条街拍美图

    01 前言 上篇文章我们爬取了今日头条街拍美图,心情相当愉悦,今天这篇文章我们使用Selenium来爬取当当网的畅销图书排行.正所谓书中自有黄金屋,书中自有颜如玉,我们通过读书学习来提高自身的才华,自 ...