由于 Java 的泛型在运行时会被擦除,不能够直接获取泛型的类型,但是其实在 class 字节码中还是保存着泛型的信息,可以通过特殊的方式获取到泛型的类型
/**
* 定义一个抽象的父类
* 获取父类中的泛型类型 T
*/
public abstract class SuperClass<T> {
// 泛型类型
private Class<T> clazz;
public SuperClass() {
super();
// 根据实现类反射获取包含泛型的父类,然后获取泛型的类型
this.clazz = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public Class<T> getClazz() {
return this.clazz;
}
public static void main(String[] args) {
// 构造匿名子类
SuperClass<String> superClassString = new SuperClass<String>(){
};
System.out.println(superClassString.getClazz()); // class java.lang.String
// 构造匿名子类
SuperClass<Entity> superClassEntity = new SuperClass<Entity>(){
};
System.out.println(superClassEntity.getClazz()); // class Entity
}
}
public interface SuperInterface<T> {
@SuppressWarnings("unchecked")
default Class<T> getEntityClass() {
Type[] types = getClass().getGenericInterfaces();
for (Type type : types) {
if (type.getTypeName().startsWith(SuperInterface.class.getName())) {
ParameterizedType pt = (ParameterizedType) type;
return (Class<T>)pt.getActualTypeArguments()[0];
}
}
return null;
}
}
public class Children implements SuperInterface<Entity> {
public static void main() {
Children children = new Children();
System.out.println(children.getEntityClass()); // class Entity
}
}
public class SystemUtils {
/**
* 根据子类获取父接口指定的泛型类型,未找到指定泛型时将返回空
*
* @param subClass 子类类型
* @param targetInterfaceClass 父接口类型
* @param genericIndex 泛型下标
* @return 泛型类型
*/
public static Class<?> getInterfaceGenericClass(Class<?> subClass, Class<?> targetInterfaceClass, int genericIndex) {
if (subClass == null || targetInterfaceClass == null || genericIndex < 0) {
return null;
}
Class<?> clazz = subClass;
while (clazz != null && clazz != Object.class) {
Type[] types = clazz.getGenericInterfaces();
for (Type type : types) {
if (type.getTypeName().contains(targetInterfaceClass.getName())) {
Type[] typeArguments = ((ParameterizedType) type).getActualTypeArguments();
if (genericIndex >= typeArguments.length) {
return null;
}
Type typeArgument = typeArguments[genericIndex];
if (typeArgument instanceof Class) {
return (Class<?>) typeArgument;
}
return null;
}
}
Class<?>[] interfaces = clazz.getInterfaces();
if (interfaces != null) {
for (Class<?> inter : interfaces) {
Class<?> result = getInterfaceGenericClass(inter, targetInterfaceClass, genericIndex);
if (result != null) {
return result;
}
}
}
clazz = clazz.getSuperclass();
}
return null;
}
public static void main(String[] args) {
System.out.println(SystemUtils.getInterfaceGenericClass(Children.class, SuperInterface.class, 0)); // class Entity
}
}
/**
* 简单 Java 对象 POJO
*/
@Getter
@Setter
class Entity {
private int id;
private String name;
}
我作为一个核专业的专业,就给大家简单的说明一下,福岛核电站泄漏事故固然有天灾的缘故,但其背后隐藏着人为设计缺陷的必然性。 一、日本处于环太平洋火山带上,是一个地震高发国家。福岛核电站就位于地震带上。而我国核电站已充分考虑了地质结构的稳定性要求,同时考虑了海啸的影响。 二、福岛核电站在全部失去场内外电源的情况下,就会失去堆芯冷却的全部功能。而我国建设的压水堆核电站即使失去全部厂内外电源,也能通过自带的气动给水泵和蒸汽排放的形式维持对堆芯的冷却。 三、福岛核电站没有安全壳。虽然在200
HTML的标签是用来指定客户端脚本的,它可以帮助我们在HTML文档中放置脚本。可以在标签内嵌入脚本代码,也可以使用src属性链接外部脚本文件。本篇文章就来给大家介绍关于html中标签元素使用方法。标签的属性在介绍标签的使用方法前,我们要先了解一下标签的属性;标签的属性有:src属性:用来指定外部脚本文件的URL,链接外部脚本文件的。type属性:用来指定脚本的媒体(MIME )类型说明:1、MIM...
三、RabbitMQ支持的消息模型RabbitMQ提供了7种消息模型,第七种是新增的模式,第6种其实是RPC,并不是MQ,因此不予学习。那么也就剩下5种。但是其实3、4、5这三种都属于订阅模型,只不过进行路由的方式不同。一.添加依赖1、java原生依赖 <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client&l
效果图: 效果分析:往上滑动scrollview当导航栏距屏幕顶部的距离小于等于标题栏的高度时 悬浮,即上滑到紧贴标题栏时 悬浮。反之:(导航栏原来的位置)下滑到距离大于标题栏的高度时将悬浮的导航栏放回原来的位置。实现步骤:1、首先是布局实现,在内容布局(标题下面的容器)中,最外层使用FrameLayout包裹住ScrollView(自定义ScrollView,写一个接口监听它的onScrollC...
一、关联查询(多表查询)1.1 笛卡尔乘积现象 交叉连接查询(不推荐。产生笛卡尔乘积现象:4 * 4=16,有些是重复记录) SELECT empName,deptName FROM employee,dept; 笛卡尔乘积现象: 假如employee有4条记录,dept有4条记录, 那么上面的sql查询结果,则为 4*4 条...
伸缩布局 lib-flexible自适应所有设备lib-flexible官方只能适配小于540分辨率的设备修改此处可适配所有function refreshRem(){ var width = docEl.getBoundingClientRect().width; if (width / dpr > 540) { //width = 540*dpr; width = width * dpr;//这里的540 替换成width } var rem = width / 10; d
众所周知,ES6虽然有着很多的兼容性问题。(使用Babel转码解决)。但是很多开发者已经在项目中用了。就算现在不打算用,为了看懂别人代码你也得懂一些ES6语法了。本文开始讲不再讲ES6和JavaScript的关系之类的东西。只是介绍ES6语法。1. 声明变量1). 现有的声明方式以前声明变量只有一种方法,那就是使用var关键字。ES6对声明进行了扩展,现在有三种声明方式:var:variable,可以理解为变量的意思let: 在英文中是 让 的意思,也可以理解为一种声明的意思const:在.
1.Form多OU实现1)创建一个Table,以CUX_OM_ORDER_HEADER_ALL为例2)创建Table的两个Synonym(一个不含_ALL,一个以_ALL结尾):CUX_OM_ORDER_HEADER和CUX_OM_ORDER_HEADER_ALL3)给不含_ALL的Synonym:CUX_OM_ORDER_HEADER加上组织屏蔽的策略函数...
可以通过Request对象完成全局输入变量的检测、获取和安全过滤,支持包括$_GET、$_POST、$_REQUEST、$_SERVER、$_SESSION、$_COOKIE、$_ENV等系统变量,以及文件上传信息。检测变量是否设置可以使用has方法来检测一个变量参数是否设置,如下:Request::instance()->has('id','get');Request::instance(...
在idea安装目录下,查看idea.vmoptions文件中设置内存的大小,可能是偏大导致电脑机器内存不够。解决办法:调小内存,调小后没有闪退。
这篇文章我们来实现笔记列表的排序和笔记本编辑删除功能,最终实现效果如下:笔记排序笔记本重命名(编辑)删除笔记本笔记排序功能用户从排序菜单中点击一个排序选项之后,笔记列表将清空,然后列表中的笔记执行排序操作,最后笔记列表会加载已排序的笔记。需要注意的地方:如果排序前笔记A高亮(预览面板的背景色加深),那么排序之后,笔记A依然需要高亮,并且文本编辑器不发生变化用户选择的排序选项需要记录下来,如果用户选...
关于大名鼎鼎的百度Echarts我就不多说了 不了解的朋友直接看官方的例子吧前阵子我加入了一个WPF的技术交流群 次demo的完成 首先得感谢群里的上进有为青年 十年 他总能发一些效果 让人看了就忍不住想想自己有没有思路实现 甚至想写写看 于是就有了此demo这个demo写了个什么东西 我先上个图吧 让大家有个直观的印象 录gif的关系 看起来可能有点卡我没用过百度Echart 所以可能和百度Ec...