泛型(来自初学者)
一、泛型的定义
1、概念
参数一般可以分为:方法调用中的形参,定义变量时实参。
事实上参数的类型也可以有这样两个分类:泛型就是方法中的变量参数将类型也定义成参数形式(类型形参),而使用这样的方法时就传入真正的类型(类型实参)。
泛型,本质上就是为参数传递增加了一个数据类型这一参数。他使得我们在参数传递中能用的数据只能是某一特定的类型。这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
2、实例解析
以下面这段代码为例:
import java.util.ArrayList;
import java.util.List;
public class test {
public static void main(String[] args) {
List list = new ArrayList();
list.add("test");
list.add(100);
for (int i = 0; i < list.size(); i++) {
String name = (String) list.get(i);
System.out.println("name:" + name);
}
}
}
报错信息:
E
x
c
e
p
t
i
o
n
i
n
t
h
r
e
a
d
"
m
a
i
n
"
j
a
v
a
.
l
a
n
g
.
C
l
a
s
s
C
a
s
t
E
x
c
e
p
t
i
o
n
Exception in thread "main" java.lang.ClassCastException
Exceptioninthread"main"java.lang.ClassCastException 原因就是由于开始建立的列表数组里有一个整型和一个字符串,而却将它用来给字符串赋值,产生了类型不匹配的矛盾。
public class test {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("test");
list.add(100);
for (int i = 0; i < list.size(); i++) {
String name = (String) list.get(i);
System.out.println("name:" + name);
}
}
}
这样修改以后,虽然列表里面装的是字符串了,但是向列表中增加数据的字符串的list.add(“test”); 语句又发生了类型不匹配的矛盾。这就提醒我们,在向列表中加入数据的时候只能加入字符串,而这一应用就是所谓的泛型。
二、泛型类
泛型类与C++的模板有相似之处,可以相互对比学习。
C++模板:
template<class T>
class example
{
private:
T x;
public:
example(T xx)
{
x=xx;
}
void output(){
cout<<x;
}
};
int main()
{
example<string> p("模板Hello world!");
p.output();
}
Java泛型:
public class test {
public static class example<T>{
public T x;
example(T xx){
x=xx;
}
public void output(){
System.out.println(x);
}
}
public static void main(String[] args) {
example<String> p=new example<String>("泛型Hello world!");
p.output();
}
}
两个主要区别是C++的模板需要提前声明,并且C++不用再在类名之后加上,其他不同之处主要由两者的语法决定。
三、泛型方法
特别注意:类型参数只能代表引用型类型,不能是原始类型。关于Java的引用值类型有哪些,可以参考这篇:https://blog.csdn.net/baidu_31657889/article/details/51939332,而Java的原始类型一般认为是byte,short,int,long,float,double,char,boolean八种。下面还以上面这段代码为例:
public class test {
public static class example{
public String x;
example(String xx){
x=xx;
}
public <T> T getnumber(T a){
return a;
}
public void output(){
System.out.println(x);
}
}
public static void main(String[] args) {
example p=new example("泛型Hello world!");
System.out.println(p.<Double>getnumber(3.14));
p.output();
}
}
四、泛型接口
实例:
class InfoImpl implements Info<String>{
private String var ;
public InfoImpl(String var){
this.setVar(var) ;
}
@Override
public void setVar(String var){
this.var = var ;
}
@Override
public String getVar(){
return this.var ;
}
}
public class GenericsDemo24{
public void main(String arsg[]){
InfoImpl i = new InfoImpl("harvic");
System.out.println(i.getVar()) ;
}
};
五、类型通配符
特点:在不确定具体参数时候,使用?代替参数类型表示未知类型,类型参数赋予不确定值。
举例:
public class test {
public static void test(List<?> list) {
List<?> list2;
list2 = new ArrayList<String>();
list2 = new ArrayList<Integer>();
list2 = new ArrayList<Object>();
}
public static void main(String[] args) {
test(new ArrayList<String>());
test(new ArrayList<Integer>());
}
}
以上便是泛型的内容。
参考资料:
1、https://github.com/datawhalechina/team-learning-program/blob/master/Java/11.%E6%B3%9B%E5%9E%8B.md
2、C++模板。
|