Happy Java:定义泛型参数的方法
在平时写代码时,可以自定义泛型类。当使用同一类型的对象时,这是非常有用的,但在实例化类之前,我们不知道它将是哪种类型。
下面让我们定义一个使用泛型参数的方法。首先,在定义一个类用到泛型时,必须使用特殊语法来支持这种类型。在下面的例子中,<T>
表示定义的类将要使用的类型:
public class MyGeneric<T> {
当然,也可以定义泛型中包含多个类的类型,比如java.util.Map
:
public class MyGeneric<T, U, V> { }
接下来,我们定义一个完整的类,其中包含ArrayList
对象,用来存放''类型的对象,并在构造方法中实例化ArrayList
对象。
import java.util.ArrayList;
public class MyGeneric<T> {
private ArrayList<T> list;
public MyGeneric() {
list = new ArrayList<T>();
}
public void add(T element) {
list.add(element);
}
}
需要注意的是,我们实际上并不是处理一个名为T
的类。相反,T
是用于创建MyGeneric
实例时使用的类型。 Java规范允许使用所需的任何标识符,但标准约定是使用单个大写字母将其与正常类名称区分开来。 现在我们已经将add
方法定义为T
类型的参数,只能使用与MyGeneric
实例构造相同的类型。 以下代码是非法的,并产生编译错误:
MyGeneric<String> rs = new MyGeneric<>();
rs.add(1); // illegal for a MyGeneric<String>
如果要从方法返回泛型类型,则可以将其作为方法签名的返回类型,定义所示:
SecureRandom random = new SecureRandom();
// 省略其他代码
public T getRandomElement() {
int index = random.nextInt(list.size());
return list.get(index);
}
getRandomElement
方法返回类型与定义类的类型是一致的。现在,我们就可以使用上面的方法,来构建类型实例。
public static void main(String [] args) {
MyGeneric<String> names = new MyGeneric<>();
names.add("zhangsan");
names.add("lisi");
names.add("wangwu");
names.add("zhaoliu");
// 随机获取list的一个元素
String name = names.getRandomElement();
System.out.println(name);
}
对String
类型变量names
的赋值是安全的,我们将始终从getRandomElement
方法获取一个字符串。 这只是因为我们使用String
类型构造了MyGeneric
实例。 add
和 getRandomElement
方法的定义与构造函数的定义具有相同的类型,编译器将强制执行此约束。 让我们尝试在构造函数中使用不同类型的MyGeneric
类,这次使用我们Integer
类:
MyGeneric<Integer> numbers = new MyGeneric<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
Integer oneNumber = numbers.getRandomElement();
System.out.println(oneNumber);
你可以在需要类处理某些类型的对象(在构建类之前不知道),以及希望编译器严格执行类型限制的情况下定义自己的泛型。这样做的主要优点是安全和方便。
最后,附上完整的实例代码:
package wicked.coo;
import java.security.SecureRandom;
import java.util.ArrayList;
/**
*
* @author i324779
*
* @param <T> 自定义泛型
*/
public class MyGeneric<T> {
SecureRandom random = new SecureRandom();
private ArrayList<T> list;
public MyGeneric() {
list = new ArrayList<T>();
}
public void add(T element) {
list.add(element);
}
public T getRandomElement() {
int index = random.nextInt(list.size());
return list.get(index);
}
public static void main(String [] args) {
MyGeneric<String> names = new MyGeneric<>();
names.add("zhangsan");
names.add("lisi");
names.add("wangwu");
names.add("zhaoliu");
// 随机获取list的一个元素
String name = names.getRandomElement();
System.out.println(name);
MyGeneric<Integer> numbers = new MyGeneric<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
Integer oneNumber = numbers.getRandomElement();
System.out.println(oneNumber);
}
}
Happy Java:定义泛型参数的方法的更多相关文章
- java(11)带参数的方法
一.java中的包(package) 1.1 包,对应到磁盘中的文件夹 1.2 新建一个class,默认保存在缺省包中 1.3 声明包的关键字:package package语句,置顶位置 1.4 导 ...
- JAVA的带参数的方法
一.带参数的方法 1.1 语法: <访问修饰符> 返回类型 <方法名>(<形式参数列表>) { //方法的 ...
- Java 传递可变参数和方法重载
形式:类型... 参数名 示例:public void show(int... a) {}; 可变参数在方法中被当作数组来处理 可变参数传值的四种方式: 一个值也不传,可变参数会接收到长度为0的数组 ...
- java不确定参数个数方法例子
package test; public class myTest { // 根据输入的参数动态生成数组 public static int max(int... param) { int max = ...
- Java 第13章 带参数的方法
带参数的方法 无参方法有那几个组成部分? 调用无参方法的两种形式是什么? 第一种:同一个类中的方法调用 直接用方法名 show(): 第二种:不同类中的方法调用 -->对象实例化 -->对 ...
- java<T>泛型
泛型 1.泛型的概述 在JDK1.5之前,把对象放入到集合中,集合不会记住元素的类型,取出时,全都变成Object类型.泛型是jdk5引入的类型机制,就是将类型参数化,它是早在1999年就制定的jsr ...
- Java反射机制二 获取方法的返回值或参数的泛型信息
在使用反射机制时,我们经常需要知道方法的参数和返回值类型,很简单 ,下面上示例,示例中的两个方法非常相似 package deadLockThread; import java.lang.refle ...
- Java方法的定义以及调用、方法重载、可变参数以及递归
目录 何谓方法 方法的定义及调用 方法的定义 方法调用 方法重载 命令行传参 可变参数 递归 何谓方法 Java方法是语句的集合,它们在一起执行一个功能 方法是解决一类问题的步骤的有序组合 方法包含于 ...
- 初识Java泛型以及桥接方法
泛型的由来 在编写程序时,可能会有这样的需求:容器类,比如java中常见的list等.为了使容器可以保存多种类型的数据,需要编写多种容器类,每一个容器类中规定好了可以操作的数据类型.此时可能会有Int ...
随机推荐
- MySQL存储引擎与数据类型
1 数据存储引擎 存储引擎的概念是MySQL的一个特性,它指定了表的类型(诸如表怎样存储与索引数据.是否支持事务.外键等),表在计算机中的存储方式. 1.1 MySql支持的数据存储引擎 查看引擎信息 ...
- dom4j解析以及生成xml字符串测试
public static void main(String[] args) { String xmlStr = "<ybjcVo>"+ "<zbGri ...
- hadoop-处理小文件
一个Hadoop程序的优化过程 – 根据文件实际大小实现CombineFileInputFormat http://www.rigongyizu.com/hadoop-job-optimize-com ...
- Python2.7.14新手学习
python2.7.14 让用户选择一个功能,然后对其进行操作的例子.中间有问题的是年龄没有做是否是数字判断 注意:和版本python3不同的地方 1.编码 2.输入地方是raw_input 3.业务 ...
- 元素高度、宽度获取 style currentStyle getComputedStyle getBoundingClientRect
1.示例代码 (1)html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node ……
解决办法是加一个等待时间即可解决问题: setTimeout(function () { you code }, );
- cocos2d-js 粒子系统使用自定义图片,还原原来的图片宽高
粒子系统使用自定义图片很简单只需要在plist最后一行设置png的名称即可.但是,在实际使用中,发现自定义图片无法使用原来的形状,例如设置了一长条的图片,结果出来确实一个个圆球. 翻了plist和cc ...
- 一个简单的ExtJS搜索建议框
封装的是一个Ext4.2的组件,继承并兼容于Ext的ComboBox. 实现原理非常easy,在 combo 中监听 keyup 事件就可以. 搜索建议的Combo.基本上全然兼容, 使用方式与Com ...
- MBTiles 1.2 规范翻译
MBTiles 1.2 可以参考超图的文档MBTiles扩展 具体实现可以参考浅谈利用SQLite存储离散瓦片的思路和实现方法 mapbox提供了一个简单实现测试代码,github地址在这里https ...
- Eclipse和MyEclipse使用技巧--Eclipse中使用Git-让版本管理更简单
详细步骤: 第一部分 GIT介绍 (1)GIT往世今生 2005年开发Samba的Andrew试图破解BitKeeper(一款商业的版本控制系统)的协议(这么干的其实也不只他一个),被BitMove ...