- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章java泛型基本知识及通用方法由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
泛型的基本使用 。
泛型是java se 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 这种参数类型可以用在类、接口和方法的创建中, 分别称为泛型类、泛型接口、泛型方法. java语言引入泛型的好处是安全简单. 。
今天就从以下几个方面介绍一下java的泛型: 基础, 泛型关键字, 泛型方法, 泛型类和接口. 。
基础
通过集合的泛型了解泛型的基本使用 。
1
2
3
4
5
6
|
public
void
testbasis(){
list<string> list =
new
arraylist<string>();
// new arraylist<int>();
}
//这是最基本的泛型使用, 就不多说了, 不过要注意的是泛型只能是引用数据类型, 不能是基本类型, 而且泛型只在编译期有效, 在编译后的class文件中是不存在泛型信息的
|
注意: 泛型只在编译期有效, 在编译后的class文件中是不存在泛型信息的 。
泛型关键字
通配符?表示任意引用类型, extends关键字表示子类及其本身, super关键字是表示父类及其本身. 通过一个例子看一下, 解释说明都在例子中 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public
void
testkeyword()
throws
exception {
//实例化参数类型必须指明具体类型
list<?> list =
new
arraylist<string>();
//由于list中类型不明确, 所以不能进行添加操作
// list.add("sk");
//通配符?表示任意引用类型
list<list<?>> list1 =
new
arraylist<list<?>>();
//list1的参数化类型是一个list, 而这个list也是一个参数化类型, 它的类型是任意类型, 所以list1可以添加任意list类型对象
list1.add(
new
arraylist<object>());
list1.add(
new
arraylist<string>());
//实例化list2时指明了类型参数list, 只不过这个list是一个泛型类型
//从这里可以看到关键字extends的用法, 其实就是继承, 如下这里的list2中的参数化类型list(在这里记为paramlist)的参数化类型是继承自number的
//所以在list2在添加的时候只能添加参数化类型为number及其子类的paramlist
list<integer> l1 =
new
arraylist<integer>();
list<number> l2 =
new
arraylist<number>();
list<object> l3 =
new
arraylist<object>();
list<list<?
extends
number>> list2 =
new
arraylist<list<?
extends
number>>();
list2.add(l1);
list2.add(l2);
// list2.add(l3); //这里使用了extends关键字, 所以不能添加number的父类
//相信大家也猜到了, 既然extends关键字表示子类及其本身, 那么super关键字是表示父类及其本身, 是的, 没错
//和上面的不一样了, l1不能添加, 因为integer是number的子类, 并不是number的父类
list<list<?
super
number>> list3 =
new
arraylist<list<?
super
number>>();
// list3.add(l1); //这里使用了super关键字, 所以不能添加number的子类
list3.add(l2);
list3.add(l3);
}
|
泛型方法
java中任何类型必须先定义才能使用, 泛型也是如此. 既然要使用泛型作为参数, 所以要先定义, 泛型的定义在访问修饰符和返回类型之间, 注意不要掉了尖括号 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
//无返回值有参的方法, 参数为泛型
public
<t>
void
show(t t){
system.out.println(
"t-=-="
+ t);
}
//有返回值的有参方法, 只有一个参数化类型, 这里定义泛型的方式和上面一样, 也是先定义后使用, 只不过这里的返回类型是泛型
public
<t> t get(t t){
return
t;
}
//有返回值的有参方法, 有多个参数化类型, 这里以两个为例
public
<t, k> k get(t t, k k){
return
k;
}
@test
public
void
testgeneric()
throws
exception {
show(
3
);
show(
"generic"
);
system.out.println(
"----------------"
);
system.out.println(
"我返回integer类型-"
+ get(
4
));
system.out.println(
"我返回string类型-"
+ get(
"returngeneric"
));
system.out.println(
"------------------"
);
system.out.println(
"我返回string类型-"
+ get(
1
,
"a"
));
system.out.println(
"我返回integer类型-"
+ get(
"b"
,
2
));
}
|
本来想写无参的泛型方法, 可是写着写着感觉那样没有什么意义, 不知道各位有什么见解. 。
泛型类和接口
写泛型类的时候只需要在类名后面加上泛型即可, 就像这样 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
class
genericclass<t> {
public
t get(t t){
return
t;
}
public
void
scr(t t){
system.out.println(t);
}
public
void
show(){
genericclass<integer> gc =
new
genericclass<integer>();
// genericclass<t> gc1 = new genericclass<t>();
gc.get(
3
);
gc.scr(
5
);
//下面2个会报错
// gc1.get(3);
// gc1.scr(5);
}
}
|
从上面的例子中可以看到, 参数化类型是在创建对象的时候具体化的, 那么除此之外, 还可以再什么时候具体化参数化类型呢?
如果是在继承或实现中, 可以在子类或实现类中确定具体类型 。
使用java泛型设计通用方法 。
泛型是java se 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 因此我们可以利用泛型和反射来设计一些通用方法. 现在有2张表, 一张user表和一张student表. 。
user
student
如果要根据id查询数据, 你会怎么做呢?写2个方法分别查询user和student?其实这时候我们就可以使用泛型和反射写一个通用的方法. 。
user的实体类
1
2
3
4
5
|
private
integer id;
private
string username;
private
string password;
private
string hobby;
//getxxx方法和setxxx方法
|
student实体类
1
2
3
4
|
private
integer id;
private
string name;
private
integer age;
//getxxx方法和setxxx方法
|
basedao接口
1
2
3
4
|
public
interface
basedao<t> {
//根据id查询的方法
t findbyid(integer id);
}
|
basedaoimpl类, 实现了basedao接口, 通用方法就在这里面完成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
//设置为抽象的, 不让他实例化, 让其子类实例化就行了
//通过泛型设计通用方法的关键就是利用反射拿到泛型的具体类型
public
abstract
class
basedaoimpl<t>
implements
basedao<t> {
private
string tablename;
//表名
private
class
<t> actualtype;
//真实类型
/**
* findbyid(integer id)这个方法被子类继承了, 假设我们在userdaoimpl中操作, 此时参数化类型t为user
* 下面的讲解都假设是在userdaoimpl中进行的
*/
//把公共部分可以放到构造方法中
@suppresswarnings
(
"unchecked"
)
public
basedaoimpl() {
//返回类型是type 是 java 编程语言中所有类型的公共高级接口. 它们包括原始类型、参数化类型、数组类型、类型变量和基本类型.
//type的已知子接口: parameterizedtype 表示参数化类型, 如 collection<string>.
//getclass()得到userdaoimpl的class, 得到class一般有3中方式: getclass(), 类名.class, class.forname()
type type = getclass().getgenericsuperclass();
//获取userdaoimpl<user>的参数化类型的父类basedaoimpl<user>
//由于我们得到的是一个参数化类型, 所以转成parameterizedtype, 因为需要使用里面的方法
parameterizedtype pt = (parameterizedtype) type;
//强转
type[] actualtypearr = pt.getactualtypearguments();
//获取真实参数类型数组[user.class], 可以调试看到这里的值
actualtype = (
class
<t>) actualtypearr[
0
];
//数组只有一个元素
tablename = actualtype.getsimplename();
}
@override
public
t findbyid(integer id) {
string sql =
"select * from "
+ tablename +
" where id = ?"
;
try
{
return
qrutils.getqueryrunner().query(sql,
new
beanhandler<t>(actualtype), id);
}
catch
(sqlexception e) {
e.printstacktrace();
}
return
null
;
}
}
|
连接数据库操作是用的c3p0和dbutils, 有关这方面的内容可以参看我以前的随笔. 。
userdao接口, 继承basedao接口
1
2
|
public
interface
userdao<t>
extends
basedao<t> {
}
|
userdaoimpl类, 实现userdao接口, 继承basedaoimpl类, 可以看到里面什么方法也没有
1
2
|
public
class
userdaoimpl
extends
basedaoimpl<user>
implements
userdao<user> {
}
|
studentdao接口, 继承basedao接口
1
2
|
public
interface
studentdao<t>
extends
basedao<t> {
}
|
studentdaoimpl类, 实现studentdao接口, 继承basedaoimpl类, 也可以看到里面什么方法也没有
1
2
|
public
class
studentdaoimpl
extends
basedaoimpl<student>
implements
studentdao<student> {
}
|
从以上dao可以看到, 我是在继承basedaoimpl类时把泛型具体化了. 。
测试
1
2
3
4
5
6
7
8
9
|
@test
public
void
testgeneric()
throws
exception {
userdao<user> userdao =
new
userdaoimpl();
system.out.println(userdao.findbyid(
1
));
system.out.println(
"-------------------"
);
studentdao<student> studentdao =
new
studentdaoimpl();
system.out.println(studentdao.findbyid(
1
));
}
|
看一下测试的结果: 同一个方法把2张表中的数据都查出来了 。
最后此篇关于java泛型基本知识及通用方法的文章就讲到这里了,如果你想了解更多关于java泛型基本知识及通用方法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
可以用这种方式转换字符串吗?我们有相同的参数,Java 做出了正确的选择。如果值是整数 - 我们调用 parseInt(value),否则如果值是 double 型 - 我们调用 parseDoubl
如果这段代码中有一个愚蠢的错误,我提前道歉,但我似乎无法解决它。我的问题是这样的,我用GCC-8(通过home-brew安装在Mac上)编译,然后在终端中执行。当使用 int do 定义变量 s &
我用 a-videosphere 制作了一个 a-scene。我尝试使用按钮启用/禁用声音,但有些想法不起作用?这是我的代码: var gargamel = 0; function
我正在使用 ISAAC 实现来生成随机整数。我需要用这些整数创建一个高斯值。首先,我需要将它们从 0 更改为 1 的 double 值。我怎样才能在Java中做到这一点?这是到目前为止我将整数转换为
我将 0x0000 到 0x01c2 范围内的十六进制值从 BLE 获取到我的手机 a 作为字符串。为了将其绘制在图表中,我必须将其转换为 double,我已经尝试过 this method但遗憾的是
我有一个父类(super class) Animal和一个子类 Dog 。在第三节课中,我有一个 List它同时接受子类型和父类(super class)型对象。 public class foo{
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 6 年前。 Improve this ques
我正在尝试查询我的用户的距离。我可以用这段代码做到这一点 PFGeoPoint.geoPointForCurrentLocationInBackground { (geoPoint: PFGe
考虑示例:http://jsfiddle.net/KWLu7/16/ 我正在尝试将总体重要性值计算为每个选定选择重要性的总和乘以其父标准重要性: var watch = $scope.$watch("
这个问题在这里已经有了答案: Bounding generics with 'super' keyword (6 个答案) 关闭 2 年前。 我有一个列表装饰器,它应该允许从一个列表转换到另一个列表
为什么下面的代码没有选择最近父类(super class)型的隐式 val? class A class B extends A trait TC[-T] { def show(t: T): Stri
这是我想要做的 def merge[A, B, C](eithers: Either[A,B]*)(implicit ev1: A x, x => x)) 关于scala - 推断常见的父类(s
我正在尝试从具有 double 类型列的Cassandra表中获取 double 值。我已经使用CQL3语法创建了表: CREATE TABLE data_double ( datetime
是否应该在不需要显式类型定义的情况下编译以下 this ? def prepList[B >: A](prefix: PlayList[B]) : PlayList[B] = prefix.fol
我正在查看某人的代码,并且在创建结构时使用了 abstract type AbstractFoo end julia> struct Foo1 struct Foo2 foo_op(x::Abst
一些示例代码: public class Main { class SomeType { } class A { protected T createSome
是否可以只接受类的泛型类型的父类(super class)型? 我正在寻找的是这样的: class MyClass { public void myMethod(TS someObject
在我的代码中,我有许多 ArrayList 被传递到排序方法中。每个 ArrayList 都有不同的泛型类型,但所有这些类型都是 Sorter 的实现。排序方法旨在接受 Sorter 类型的 Arra
如果已经有人问过这个问题,请链接并关闭这个问题。 我目前正在为另一个使用起来复杂得多(并且有潜在危险)的 API 的简化 API 设计原型(prototype)。 考虑到相关的有点复杂的对象创建,我决
我正在尝试构建一个具有某些依赖项的 android 应用程序,但是其中一个导致了此错误: Illegal class file: Class module-info is missing a supe
我是一名优秀的程序员,十分优秀!