) IDENTITY_FN;
}
在深入理解 Java Object一文中介绍的比较两个对象是否相等的equals方法,就会发现使用的不是泛型,实现比较的代码就比较冗长且模版化
PhoneNumber.java
@Override
public boolean equals(Object o) {
//判断引用是否相等
if (o == this) {
return true;
}
if (!(o instanceof PhoneNumber)) {
return false;
}
PhoneNumber pNum = (PhoneNumber) o;
...
而对象如果要比较排序的话,通常需要实现下面这个泛型接口
public interface Comparable {
int compareTo(T o);
}
类型参数T限制了需要比较的对象的类型,因为绝大部分比较都是在同类型之间进行,这个方法的复写就比equals简洁的多
PhoneNumber.java
public class PhoneNumber implements Comparable {
@Override
public int compareTo(PhoneNumber phoneNumber) {
int result = Short.compare(areaCode, phoneNumber.areaCode);
if (result == 0) {
result = Short.compare(prefix, phoneNumber.prefix);
if (result == 0) {
result = Short.compare(linNum, phoneNumber.linNum);
}
}
return result;
}
}
Comparable接口出现在泛型方法中通常都伴随着一个令人头疼的名字:递归类型限制,如下所示的>
public static > E max(Collection c);
类型限制>可以读作针对可以与自身进行比较的每个类型E,也就是列表中的每个元素E都是可以互相比较的。
总之,泛型方法和泛型一样,不需要转化参数就能使用,这样更加安全简洁,所以尽可能将方法泛型化。
Item 31 使用有限制通配符提升API的灵活性
在Item 28中提到过:参数化类型是不可变的。比如Integer是Number的子类,但List并不是List的子类,导致下面的例子编译不通过,这种无限制的类型参数降低了代码的灵活性
public class Test {
public static void main(String[] args) {
List integers=new ArrayList<>(10);
integers.add(2);
//print(integers);编译不通过
}
public static void print(List number){
System.out.println(number.toString());
}
}
还好Java提供了一种有限制的通配符类型解决这类问题,我们对print方法作如下修改,这时输入参数的含义就不是Number的集合,而是Number的某个子类的集合(包括Number自己)。但示例仅仅说明有限制的通配符类型,并没有涉及泛型
public class Test {
public static void main(String[] args) {
List integers=new ArrayList<>(10);
integers.add(2);
print(integers);
}
//使用有限制的通配符类型
public static void print(List number){
System.out.println(number.toString());
}
}
在Item 29我们有个泛型类Stack
public class Stack {
public Stack();
public void push(E e);
public E pop();
public boolean isEmpty();
}
如果我们添加一个方法addAll,按照之前的思路会是下面这个样子
public void pushAll(Iterable src) {
for (E e : src)
push(e);
}
如果一个名为Obj的对象是E的子类,调用push(Obj)没有问题,但如前文所述,调用pushAll(Iterable)就不行,解决方案就是改成下面这个样子
public void pushAll(Iterable src) {
for (E e : src)
push(e);
}
如果再添加一个方法,把Stack所有元素弹出到某个集合中,根据经验应该写成这样,其实这样编译不通过的,Java中父类引用可以指向子类对象,但反过来不行,下面就犯了这个错误,dst中的引用是E的子类类型,pop返回的是E,就好像往List添加Nubmer,所以无法添加
public void popAll(Collection dst) {
while (!isEmpty())
dst.add(pop());
}
知道错误在哪就好办了,只要 限定dst中元素引用是E的父类类型即可,只要把extends改成super即可
public void popAll(Collection dst) {
while (!isEmpty()) dst.add(pop());
}
关于使用extends还是super有一个口诀
- 如果输入参数是生产者,如addAll的参数,使用extends
- 如果是消费者,如popAll的参数,使用super
在上一节有这样一个泛型方法,之前也提到了这种输入参数和返回参数类型都一致的泛型不够灵活,只能是同一种类型
public static Set union(Set s1, Set s2) {
Set result = new HashSet<>(s1);
result.addAll(s2);
return result;
}
这个方法如果想把Integer类型和Double类型合并就做不到,所以需要使用有限制的通配符类型,两个参数都是生产者,修改如下,注意返回参数类型没变
public static Set union(Set s1, Set s2) {
Set result = new HashSet<>(s1);
result.addAll(s2);
return result;
}
这种带泛型的有限通配符类型方法使用起来就更加灵活
public static void main(String[] args) {
//Set没有of这个方法,编译是不通过的,为了演示简洁
Set integers = Set.of(1, 3, 5);
Set doubles = Set.of(2.0, 4.0, 6.0);
//Java 8可以推导出E的类型为Number
Set numbers = union(integers, doubles);
//Java 8 之前无法推导出,需要使用显示的类型参数
// Set numbers2 = Test.union(integers, doubles);
}
现在回头看Item 30的max方法,发现也有优化空间
- 参数c是生产者,从Collection改成Collection<? extends E>
- Comparable始终是消费者,Comparable优于Comparable
//优化前
public static > E max(Collection c);
//优化后
public static > E max(Collection c);
举个例子说明这样优化的好处,下面代码来自JDK。Delayed接口继承了Comparable接口,类型参数为Delayed
public interface Delayed extends Comparable {
long getDelay(TimeUnit unit);
}
ScheduledFuture又继承了Delayed接口,所以间接的继承了Comparable接口,但是Comparable的类型参数不是ScheduledFuture,而是父类Delayed
public interface ScheduledFuture extends Delayed, Future {
}
所以下面这个集合就不能传入优化前的max方法
List> scheduledFutures = ... ;
因为ScheduledFuture没有 extends Comparable< ScheduledFuture >,而是extends Comparable,Delayed是Comparable的父类。但优化后的max就可以,因为Comparable的类型参数声明为E,也就是这里的ScheduledFuture的父类。
关于类型参数和通配符还有一些值得讨论,比如下面两个交换元素的静态方法,如果类型参数只在方法中出现一次,就可以用通配符替换
//使用类型参数实现
public static void swap(List list, int i, int j);
//使用通配符实现,更简单
public static void swap(List list, int i, int j);
虽然推荐第二种方法,但List有一个问题,就是除了Null,不能添加其它元素,好在我们有一个辅助方法弥补这个缺陷
public static void swap(List list, int i, int j) {
swapHelper(list, i, j);
}
//使用私有的方法捕获通配符类型
private static void swapHelper(List list, int i, int j) {
list.set(i, list.set(j, list.get(i)));
}
总的来说使用通配符让API更加灵活,基本原则就是
- 生产者使用extends
- 消费者使用super,所有的comparables 和 comparators 都是消费者
Item 32 谨慎结合泛型和可变参数
可变参数可以极大的方便方法的调用,它允许给一个方法传递可变数量的参数,如下所示
public static void main(String[] args) {
show("one","two");
show("one","two","three");
}
public static void show(String... msgs) {
for (String string : msgs) {
System.out.println(string);
}
}
但这样你可能还不满足,参数String是具体类型,如果改成下面这样的泛型参数岂不更妙,
public static void main(String[] args) {
show("one","two");
show(1,3,4);
show(1.2f,3,4f);
}
public static void show(T... msgs) {
for (T string : msgs) {
System.out.println(string);
}
}
虽然运行是没问题的,但有些智能编辑器会警告你:msgs这个可变参数会导致堆污染。可变参数是这样实现的,当调用方法时,创建数组来保存可变长的参数,泛型在编译的时候被擦除,所以所以T... msgs就变成了Object[],但在运行的时候,这个应用指向的类型可能是String[]、Interger[]等,也就是编译时类型和运行时类型不匹配导致的堆污染,容易出现类型转换异常。看下面这个示例。
static void dangerous(List... stringLists) {
List intList = List.of(42);
//stringLists=List[],数组时协变类型,没有问题
Object[] objects = stringLists;
//object[0]的引用是参数化类型List,指向了参数化类型对象List,导致堆污染
objects[0] = intList;
// 虽然没有显式的cast,但会报ClassCastException
String s = stringLists[0].get(0);
}
在Item 28里说过像new E[],new List[]这样的显式的泛型数组或参数化类型数组是不合法的,但可变参数却可以隐式的使用它们,这是因为泛型和参数化类型的数组在实际开发中实在太好用了,就破例允许这种不一致的存在,下面是JDK一些源码示例。
Arrays.java
@SafeVarargs
@SuppressWarnings("varargs")
public static List asList(T... a) {
//注意:此处ArrayList为Arrays的私有静态内部类
return new ArrayList<>(a);
}
Collections.java
@SafeVarargs
public static boolean addAll(Collection c, T... elements) {
boolean result = false;
for (T element : elements)
result |= c.add(element);
return result;
}
EnumSet.java
@SafeVarargs
public static > EnumSet of(E first, E... rest) {
EnumSet result = noneOf(first.getDeclaringClass());
result.add(first);
for (E e : rest)
result.add(e);
return result;
}
作者只有在确定可变参数是类型安全的,才可以使用@SafeVarargs注解告知编译器不要警告,那怎样才是安全的,需要满足以下条件
- 不要使用可变参数存储任何值,很容易导致类型不匹配
- 不要暴露可变参数的引用
//使用可变参数存储了其它值,违反第一条
objects[0] = intList;
//暴露了可变参数引用,违反了第二条
static T[] toArray(T... args) {
return args;
}
下面一个示例使用了上面的toArray方法,编译运行都是正常的,但要注意返回数组的类型是由传入的参数的编译时类型决定的,编译器可能没有足够的信息作准确的判断
public static void main(String[] args) {
//传人的参数编译时类型为String
String[] msg=toArray("one","two");
//为Integer
Integer[] integer=toArray(1,3,4);
}
//下面是反编译的字节码 参数类型都变成了Object,但做了正确的类型转换
invokestatic Method toArray:([Ljava/lang/Object;)[Ljava/lang/Object;
checkcast class "[Ljava/lang/String;"
invokestatic Method toArray:([Ljava/lang/Object;)[Ljava/lang/Object;
checkcast class "[Ljava/lang/Integer;"
如果上面这个可以使用,下面这个应该也没什么问题
public static void main(String[] args) {
String[] reuslt=pickTwo("t1", "t2");
}
static T[] pickTwo(T a, T b,) {
switch(ThreadLocalRandom.current().nextInt(3)) {
case 0: return toArray(a, b);
case 1: return toArray(a, c);
case 2: return toArray(b, c);
}
throw new AssertionError(); // Can't get here
}
//没有checkcast,返回的就是Object数组,实际类型信息丢失
invokestatic Method toArray:([Ljava/lang/Object;)[Ljava/lang/Object;
invokestatic Method pickTwo(Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
checkcast class "[Ljava/lang/String;"
实际上编译的时候确实没有问题,但运行起来就会报错:ava.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
因为此时toArray接受到的参数编译时类型为Object,所以返回的是Object数组,pickTwo接受到的也是Object数组,强转成String[]就报错。如果如下去除泛型,确定pickTwo的参数类型,也不会报错,只是没什么意义。
static String[] pickTwo(String t1,String t2){
return toArray(t1,t2);
}
下面是一个典型的正确使用泛型可变参数的案例,注意:@SafeVarargs只能用在静态方法、不可覆盖方法和私有方法上(Java 9)
@SafeVarargs
static List flatten(List... lists) {
List result = new ArrayList<>();
for (List list : lists)
result.addAll(list);
return result;
}
如果你不想使用麻烦的泛型可变参数,可以使用集合替代,并配合Java 9中的List.of,它使用了@safeVarargs注解,是类型安全的
static List flatten(List> lists) {
List result = new ArrayList<>();
for (List list : lists)
result.addAll(list);
return result;
}
不过下面原书的例子我觉得是有问题的,编译不通过,参数类型不匹配
audience = flatten(List.of(friends, romans, countrymen));
前面有问题的代码就可以用集合解决,
public static void main(String[] args) {
List attributes = pickTwo("Good", "Fast", "Cheap");
}
static List pickTwo(T a, T b, T c) {
switch(rnd.nextInt(3)) {
case 0: return List.of(a, b);
case 1: return List.of(a, c);
case 2: return List.of(b, c);
}
throw new AssertionError();
}
总的来说,可变参数底层使用的是数组,和泛型配合不好,如果可变参数要结合泛型,一定要遵守下面事项,保证安全才能用@safeVarargs注解
- 它没有在可变参数数组中保存任何值
- 它没有对不被信任的代码开发该数组
Item33 优选类型安全的异构容器
虽然按照规则使用泛型可以保证类型是安全的,但如果和原始类型混用泛型就有类型安全隐患,下面段代码编译的时候有unchecked warning,但可以运行,也就是整数1添加到了类型参数为String的集合中,只要不取出来涉及类型转换就不会发现问题
List a=new ArrayList<>();
//使用原始类型绕过泛型检查
List b=a;
//成功添加
b.add(1);
这是一种隐患,对于错误应该越早发现越好。Java SDK的Conllections工具类提供如下解决方法,除了泛型,还添加了String.class这个字面量,其传到方法作为参数表示的是Class,它可以作为类型令牌
//checkedList返回一个对ArrayList的包装类
List c=Collections.checkedList(new ArrayList<>(), String.class) ;
List d=c;
//添加失败
d.add(1);
//Collections.java
public static List checkedList(List list, Class type) {
return (list instanceof RandomAccess ?
new CheckedRandomAccessList<>(list, type) :
new CheckedList<>(list, type));
}
上面这段代码编译的时候也有unchecked ,但运行就会报ClassCastException,原理就是添加之前利用Class这个类型令牌作类型检查
Collections.CheckedCollection.java
public boolean add(E e) {
return c.add(typeCheck(e));
}
E typeCheck(Object o) {
//类型检查
if (o != null && !type.isInstance(o))
throw new ClassCastException(badElementMsg(o));
return (E) o;
}
你可能感兴趣的:(Java泛型)
- Java泛型类型擦除问题
ikt4435
编程程序员Javajava开发语言
以前就了解过Java泛型的实现是不完整的,最近在做一些代码重构的时候遇到一些Java泛型类型擦除的问题,简单的来说,Java泛型中所指定的类型在编译时会将其去除,因此List和List在编译成字节码的时候实际上是一样的。因此java泛型只能做到编译期检查的功能,运行期间就不能保证类型安全。我最近遇到的一个问题如下:假设有两个bean类/**Test.*/@Data@NoArgsConstructo
- Java——通配符以及上下限
六七_Shmily
javajavawindows开发语言
在Java泛型中,通配符?用于表示未知类型,通常用于增强泛型的灵活性。通配符可以与上限和下限结合使用,进一步限制类型的范围。以下是通配符及其上下限的详细介绍:一、通配符?的基本用法通配符?表示未知类型,可以用于泛型类、泛型接口和泛型方法的参数类型。示例:使用通配符//定义一个方法,接受任意类型的ListpublicstaticvoidprintList(Listlist){for(Objectel
- 深入解析Java泛型上下界:extends与super的精妙应用
多多的编程笔记
Java基础java开发语言
泛型上下界:学习extends和super的使用泛型编程是一种强大的编程范式,它在编译时提供了类型安全,同时在运行时保持了类型的灵活性。Java中的泛型通过extends和super关键字来实现类型的上下界约束。本篇文章将深入探讨这两个关键字的用法,并通过实际案例来展示它们在泛型编程中的应用。一、extends关键字extends关键字用于指明泛型类型参数的上下界,即它定义了泛型类型参数的继承范围
- Java高频面试之SE-20
牛马baby
java面试开发语言
hello啊,各位观众姥爷们!!!本baby今天又来了!哈哈哈哈哈嗝Java的泛型是什么?Java泛型(Generics)是Java5引入的一项重要特性,用于增强代码的类型安全性和重用性。泛型允许在定义类、接口和方法时使用类型参数,从而使代码更加通用且减少类型转换的需求。1.泛型的基本概念泛型的核心思想是参数化类型,即在定义类、接口或方法时,使用一个或多个类型参数(通常用T、E、K、V等表示),在
- 彻底搞懂了 泛型上下边界!跟普通泛型比,抽象层级都不同!
弹唱Tan
java语言
和是Java泛型中的“通配符(Wildcards)”和“边界(Bounds)”的概念。:是指“上界通配符(UpperBoundsWildcards)”:是指“下界通配符(LowerBoundsWildcards)泛型可以是看成容器里元素的尺子。往容器里放,元素必须比每把尺子都要小;取出的时候,必须用比最大的尺子还要大的引用来接收::这里T就是对元素要求的尺子;尺子只有T一把和:这里面的?是对尺子的
- Java泛型深度解析(JDK23)
代数狂人
Javajava开发语言
第一章泛型革命1.1类型安全的进化史前泛型时代的类型转换隐患代码的血泪史(Java1.4版示例):ListrawList=newArrayList();rawList.add("Java");rawList.add(Integer.valueOf(42));//编译通过//灾难在运行时爆发StringfirstElement=(String)rawList.get(0);//正常Stringsec
- Java泛型详解
学习两年半的Javaer
Java基础java
Java泛型是JavaSE5引入的重要特性,旨在增强类型安全性和代码重用性。以下是对Java泛型的详细讲解,结合核心概念和实际示例:一、泛型的目的类型安全:编译时检查类型,避免运行时的ClassCastException。消除强制转换:减少代码冗余和潜在错误。代码复用:通过参数化类型编写通用代码。示例(无泛型的问题):Listlist=newArrayList();list.add("Hello"
- Java泛型详解 | 最新、全面、详细和深入 | 2万字超全
快乐随风起
JVMJava笔记javajvm开发语言
目录1泛型概述1.1前言1.2泛型的定义1.3Java泛型的作用2Java泛型的特点2.1类型擦除2.2类型擦除原则2.3类型擦除带来的影响2.4弱记忆3泛型的使用3.1泛型类3.1.1泛型类的使用3.1.2泛型类派生子类注意点3.2泛型接口3.2.1泛型接口的使用3.2.2泛型接口实现类注意点3.3泛型通配符3.3.1前言案例3.3.2什么是类型通配符3.4泛型上下界3.5泛型方法3.5.1泛型
- java 泛型 json_Java泛型与Json反序列化
KateZeng
java泛型json
Java的JSON库有很多,本文分析google的Gson和alibaba的fastjson,在Java泛型场景反序列化的一些有意思的行为。考虑下面的json字符串:["2147483648","2147483647"]用fastjson在不指定类型的情况下解析,下面的代码输出啥:JSON.parseArray(s).forEach(o->{System.out.println(o.getClas
- Java中的泛型及其用途是什么?
计算机学长大白
javapython开发语言
Java中的泛型(Generics)是Java语言在2004年引入的一项重要特性,用于增强代码的类型安全性和复用性。泛型允许程序员在定义类、接口或方法时指定类型参数,从而实现对不同数据类型的统一操作。本文将详细探讨Java泛型的概念、用途以及具体实现方式,并通过示例代码展示其应用。一、Java泛型的基本概念1.泛型的定义泛型是一种参数化类型,允许在定义类、接口或方法时使用类型参数。这些类型参数可以
- Java 核心与应用:Java 泛型编程
星核日记
《Java核心与应用》javapython开发语言
目录Java核心与应用:Java泛型编程引言1.泛型编程基础1.1什么是泛型?1.1.1泛型的使用场景1.1.2类型安全演进史1.2泛型的优势1.2.1泛型与普通代码的对比2.类型擦除与桥接方法2.1类型擦除机制2.1.1类型擦除示例2.2桥接方法2.2.1桥接方法示例3.泛型通配符与PECS原则3.1泛型通配符3.1.1通配符示例3.2PECS原则3.2.1PECS示例4.泛型在反射中的类型获取
- 深入理解Java泛型
wh柒八九
核心知识点java相关java面试
作为一个Java程序员,日常编程早就离不开泛型。泛型自从JDK1.5引进之后,真的非常提高生产力。一个简单的泛型T,寥寥几行代码,就可以让我们在使用过程中动态替换成任何想要的类型,再也不用实现繁琐的类型转换方法。文章目录概述Java泛型实现方式类型擦除带来的缺陷不支持基本数据类型运行效率运行期间无法获取泛型实际类型Java泛型历史背景本文小结概述泛型虽然我们每天都在用,但是还有很多同学可能并不了解
- 八股——Java基础(四)
八月五
面试题java
目录一、泛型1.Java中的泛型是什么?2.使用泛型的好处是什么?3.Java泛型的原理是什么?什么是类型擦除?4.什么是泛型中的限定通配符和非限定通配符?5.List和List之间有什么区别?6.可以把List传递给一个接受List参数的方法吗?7.Array中可以用泛型吗?8.判断ArrayList与ArrayList是否相等?二、序列化1.Java序列化与反序列化是什么?2.为什么需要序列化
- java学习记录17
cwtlw
java学习总结java学习开发语言笔记
泛型泛型概念Java泛型(generics)是JDK5引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,即给类型指定一个参数,然后在使用时再指定该参数的值,那么这个类型就可以在使用时决定了。这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。publicclassTestClass{privateTvalu
- Java 泛型及其优势
码农小灰
面试题java开发语言java
目录一、Java泛型简介二、Java泛型的优势(一)类型安全(二)消除类型转换(三)代码复用(四)可读性三、Java泛型的使用场景(一)集合框架(二)算法和数据结构(三)类和接口(四)数据库操作四、Java泛型示例代码(一)泛型类示例(二)泛型方法示例五、总结在Java编程中,泛型是一种强大的工具,它允许我们在编写代码时使用参数化类型,从而提高代码的灵活性和可重用性。本文将深入探讨Java泛型的工
- Java【泛型】
SkyrimCitadelValinor
Java基础java
Java泛型的概述不同类的数据如果封装方法相同,不必为每一种类单独定义一个类,只需定义一个泛型类,减少类的声明,提高编程效率。通过准确定义泛型类,可避免对象类型转换时产生的错误。泛型又提供了一种类型安全检测机制,只有数据类型相匹配的变量才能正常的赋值,否则编译器就不通过。Java中的泛型与C++类模板的作用相同,但是编译方式不同,Java泛型类只会生成一部分目标代码,牺牲运行速度,而C++的类模板
- Java泛型编程
shymoy
java开发语言
文章目录为什么需要泛型如何实现技术细节泛型数组泛型类型实现接口接收参数小结为什么需要泛型如果为每一种类型都写一个类来适配,会造成code冗长且难读,所以需要写一个同一的抽象的方法来实现,并让编译器自动的传入这些类型。如何实现通常放在类后面的尖括号里publicclassGenertic{}也可以指代多个publicclassGenertic{}这个类中的变量都可以用K和V来表示了泛型不仅可以应用在
- Java 类型擦除机制详解
项目笔记与工具库
java开发语言
Java的类型擦除机制(TypeErasure)是Java泛型中一个非常重要的特性。通过类型擦除,Java既实现了泛型功能,又能保持与旧版本的向后兼容性。本文将详细介绍Java类型擦除机制的工作原理、步骤、影响以及相关示例。什么是类型擦除?类型擦除是指在编译时,Java编译器会将泛型类型转换为原始类型(rawtype),并删除或替换与类型参数相关的类型信息。换句话说,在编译后的字节码中,泛型的具体
- Java泛型中 T 与 T的区别和用法
Java大数据布道者
T表示返回值是一个泛型,传递啥,就返回啥类型的数据,而单独的T就是表示限制你传递的参数类型,这个案例中,通过一个泛型的返回方式,获取每一个集合中的第一个数据,通过返回值T和T的两种方法实现一、T用法TT.png二、T用法T.pnggoldmei.png
- Java泛型基础概念
项目笔记与工具库
java开发语言
Java泛型是JavaSE5引入的一种特性,允许在编写代码时指定类、接口或方法的类型参数。通过泛型,你可以编写更具通用性、类型安全的代码,避免在运行时遇到不必要的类型转换错误。1.泛型的基本语法泛型的基本形式如下:classBox{privateTt;publicvoidset(Tt){this.t=t;}publicTget(){returnt;}}这里,T是一个类型参数,可以被任何类型替代。当
- JAVA泛型的使用场景与常见问题
项目笔记与工具库
java进阶java开发语言
泛型(Generics)是编程语言中的一种特性,允许在定义类、接口和方法时使用类型参数,从而提高代码的重用性和类型安全性。本文将详细讲解泛型的使用场景、常见问题,并深入了解类型擦除机制。一、泛型的使用场景1.提高代码的类型安全性示例:在没有泛型的情况下,使用集合需要进行显式类型转换,可能导致运行时错误。Listlist=newArrayList();list.add("Hello");Intege
- 了解泛型的类型擦除吗?
seven97_top
Javajava
概念Java泛型(generics)是JDK5中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,即给类型指定一个参数,然后在使用时再指定此参数具体的值,那样这个类型就可以在使用时决定了。这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。优点在编译的时候检查类型安全;使用泛型可以在编译时期进行类型检查,从
- Java-泛型
ZHOU_VIP
MACjava
Java泛型是一个强大的特性,它允许你在编写代码时使用类型参数来提高代码的复用性和类型安全性。以下是从入门到精通的Java泛型指南,包括基本概念、使用方法以及高级主题。1.泛型的基本概念1.1什么是泛型?泛型是一种在编译时检查类型安全,并且所有的强制转换都是自动和隐式的编程构造。使用泛型可以避免在运行时进行类型转换错误,并且可以使代码更加灵活和易于维护。1.2为什么使用泛型?类型安全:避免运行时出
- 2022年Android中高级面试框架
Swuagg
简历与面试Android中高级面试内容
目录Java泛型集合ArrayListLinkedListHashMapLinkedHashMapConcurrentHashMap多线程并发volatile线程反射JVM类加载怎么判断对象是否已死?垃圾回收机制四大引用泛型集合——HashMap、ConcurrentHashMap源码和数据结构多线程反射JVM——类加载、内存模型、内存管理机制、垃圾回收机制Android四大组件和Fragment
- 10_Java泛型
DustinWangq
Java高级编程java泛型
一、为什么要有泛型1.泛型的设计背景集合容器类在设计阶段/声明阶段不能确定这个容器到底实际存的是什么类型的对象,所以在JDK1.5之前只能把元素类型设计为Object,JDK1.5之后使用泛型来解决。因为这个时候除了元素的类型不确定,其他的部分是确定的,例如关于这个元素如何保存,如何管理等是确定的,因此把元素的类型设计成一个参数,这个类型参数叫做泛型。Collection,List,ArrayLi
- 【JAVA】java泛型 详解
CodeCharm——CC
JAVA杂项java开发语言
java泛型详解一、参数化类型(ParameterizedType):二.泛型类(GenericClass):三.泛型方法(GenericMethod):四.通配符类型(WildcardType):五.类型擦除(TypeErasure):六.自动装箱和拆箱(AutoboxingandUnboxing):Java泛型是一种在编写类、接口和方法时使用参数化类型的机制,它提供了更强大的类型安全性、代码重
- java 泛型----T、?的使用
ok060
java开发语言
java中T表示泛型。?表示不确定的类型。jdk使用K表示键,V表示值,T表示type类型,E表示enum枚举。这四个符号只是表示泛型名称,可以换成其他字母,但是需要在之前声明。参考文章:java泛型:T与?的使用及区别_javamap?和t用法-CSDN博客示例代码如下:packagejavaCode;importjava.util.HashMap;importjava.util.List;im
- 详解Java泛型之1——入门泛型必懂的知识点
测试开发Kevin
我相信,绝大多数初始Java泛型的同学都会感到这个知识点理解起来有些困难,在这里我会对java泛型相关知识点做一个详细的介绍,包括:入门泛型必懂的知识点、通配符、泛型擦除以及泛型应用四个内容。今天我来讲解第一个知识点:入门泛型必懂的知识点。先帮大家扫清泛型基础概念的相关知识点,也欢迎大家持续关注我的后续文章。泛型定义泛型的英文是generics,generic的意思是通用,而翻译成中文,泛应该意为
- 学习记录(自用)
weixin_33962621
java大数据数据库
Java学习路径及记录,纯粹个人自用,请多指教JavaJava基础常用类常用类8种基础数据类型的包装类自动打包/解包序列化深入理解Java序列化深度解析JAVA序列化异常处理JavaSE基础:异常处理六个例子彻底理解finally语句块JVM原理Java高级特性泛型Java泛型详解细说Java泛型及其应用细说Java泛型及其应用反射注解Java注解完全解析Java网络编程Java多线程编程线程基础
- Java泛型:详解使用技巧及举例说明
一休哥助手
javajava开发语言
Java泛型:详解使用技巧及举例说明1.引言Java泛型是一项强大的编程概念,它允许我们编写通用的代码,在编写代码时不需要预先指定具体的数据类型。泛型的引入解决了在传统的编程中需要频繁进行类型转换的问题,提高了代码的安全性和可读性。泛型的概念泛型是一种参数化类型的概念,它使得类、接口、方法可以在定义时使用未知的类型。通过在声明时使用类型参数,可以在使用时指定具体的类型。例如,List中的就是一个类
- Java 并发包之线程池和原子计数
lijingyao8206
Java计数ThreadPool并发包java线程池
对于大数据量关联的业务处理逻辑,比较直接的想法就是用JDK提供的并发包去解决多线程情况下的业务数据处理。线程池可以提供很好的管理线程的方式,并且可以提高线程利用率,并发包中的原子计数在多线程的情况下可以让我们避免去写一些同步代码。
这里就先把jdk并发包中的线程池处理器ThreadPoolExecutor 以原子计数类AomicInteger 和倒数计时锁C
- java编程思想 抽象类和接口
百合不是茶
java抽象类接口
接口c++对接口和内部类只有简介的支持,但在java中有队这些类的直接支持
1 ,抽象类 : 如果一个类包含一个或多个抽象方法,该类必须限定为抽象类(否者编译器报错)
抽象方法 : 在方法中仅有声明而没有方法体
package com.wj.Interface;
- [房地产与大数据]房地产数据挖掘系统
comsci
数据挖掘
随着一个关键核心技术的突破,我们已经是独立自主的开发某些先进模块,但是要完全实现,还需要一定的时间...
所以,除了代码工作以外,我们还需要关心一下非技术领域的事件..比如说房地产
&nb
- 数组队列总结
沐刃青蛟
数组队列
数组队列是一种大小可以改变,类型没有定死的类似数组的工具。不过与数组相比,它更具有灵活性。因为它不但不用担心越界问题,而且因为泛型(类似c++中模板的东西)的存在而支持各种类型。
以下是数组队列的功能实现代码:
import List.Student;
public class
- Oracle存储过程无法编译的解决方法
IT独行者
oracle存储过程
今天同事修改Oracle存储过程又导致2个过程无法被编译,流程规范上的东西,Dave 这里不多说,看看怎么解决问题。
1. 查看无效对象
XEZF@xezf(qs-xezf-db1)> select object_name,object_type,status from all_objects where status='IN
- 重装系统之后oracle恢复
文强chu
oracle
前几天正在使用电脑,没有暂停oracle的各种服务。
突然win8.1系统奔溃,无法修复,开机时系统 提示正在搜集错误信息,然后再开机,再提示的无限循环中。
无耐我拿出系统u盘 准备重装系统,没想到竟然无法从u盘引导成功。
晚上到外面早了一家修电脑店,让人家给装了个系统,并且那哥们在我没反应过来的时候,
直接把我的c盘给格式化了 并且清理了注册表,再装系统。
然后的结果就是我的oracl
- python学习二( 一些基础语法)
小桔子
pthon基础语法
紧接着把!昨天没看继续看django 官方教程,学了下python的基本语法 与c类语言还是有些小差别:
1.ptyhon的源文件以UTF-8编码格式
2.
/ 除 结果浮点型
// 除 结果整形
% 除 取余数
* 乘
** 乘方 eg 5**2 结果是5的2次方25
_&
- svn 常用命令
aichenglong
SVN版本回退
1 svn回退版本
1)在window中选择log,根据想要回退的内容,选择revert this version或revert chanages from this version
两者的区别:
revert this version:表示回退到当前版本(该版本后的版本全部作废)
revert chanages from this versio
- 某小公司面试归来
alafqq
面试
先填单子,还要写笔试题,我以时间为急,拒绝了它。。时间宝贵。
老拿这些对付毕业生的东东来吓唬我。。
面试官很刁难,问了几个问题,记录下;
1,包的范围。。。public,private,protect. --悲剧了
2,hashcode方法和equals方法的区别。谁覆盖谁.结果,他说我说反了。
3,最恶心的一道题,抽象类继承抽象类吗?(察,一般它都是被继承的啊)
4,stru
- 动态数组的存储速度比较 集合框架
百合不是茶
集合框架
集合框架:
自定义数据结构(增删改查等)
package 数组;
/**
* 创建动态数组
* @author 百合
*
*/
public class ArrayDemo{
//定义一个数组来存放数据
String[] src = new String[0];
/**
* 增加元素加入容器
* @param s要加入容器
- 用JS实现一个JS对象,对象里有两个属性一个方法
bijian1013
js对象
<html>
<head>
</head>
<body>
用js代码实现一个js对象,对象里有两个属性,一个方法
</body>
<script>
var obj={a:'1234567',b:'bbbbbbbbbb',c:function(x){
- 探索JUnit4扩展:使用Rule
bijian1013
java单元测试JUnitRule
在上一篇文章中,讨论了使用Runner扩展JUnit4的方式,即直接修改Test Runner的实现(BlockJUnit4ClassRunner)。但这种方法显然不便于灵活地添加或删除扩展功能。下面将使用JUnit4.7才开始引入的扩展方式——Rule来实现相同的扩展功能。
1. Rule
&n
- [Gson一]非泛型POJO对象的反序列化
bit1129
POJO
当要将JSON数据串反序列化自身为非泛型的POJO时,使用Gson.fromJson(String, Class)方法。自身为非泛型的POJO的包括两种:
1. POJO对象不包含任何泛型的字段
2. POJO对象包含泛型字段,例如泛型集合或者泛型类
Data类 a.不是泛型类, b.Data中的集合List和Map都是泛型的 c.Data中不包含其它的POJO
- 【Kakfa五】Kafka Producer和Consumer基本使用
bit1129
kafka
0.Kafka服务器的配置
一个Broker,
一个Topic
Topic中只有一个Partition() 1. Producer:
package kafka.examples.producers;
import kafka.producer.KeyedMessage;
import kafka.javaapi.producer.Producer;
impor
- lsyncd实时同步搭建指南——取代rsync+inotify
ronin47
1. 几大实时同步工具比较 1.1 inotify + rsync
最近一直在寻求生产服务服务器上的同步替代方案,原先使用的是 inotify + rsync,但随着文件数量的增大到100W+,目录下的文件列表就达20M,在网络状况不佳或者限速的情况下,变更的文件可能10来个才几M,却因此要发送的文件列表就达20M,严重减低的带宽的使用效率以及同步效率;更为要紧的是,加入inotify
- java-9. 判断整数序列是不是二元查找树的后序遍历结果
bylijinnan
java
public class IsBinTreePostTraverse{
static boolean isBSTPostOrder(int[] a){
if(a==null){
return false;
}
/*1.只有一个结点时,肯定是查找树
*2.只有两个结点时,肯定是查找树。例如{5,6}对应的BST是 6 {6,5}对应的BST是
- MySQL的sum函数返回的类型
bylijinnan
javaspringsqlmysqljdbc
今天项目切换数据库时,出错
访问数据库的代码大概是这样:
String sql = "select sum(number) as sumNumberOfOneDay from tableName";
List<Map> rows = getJdbcTemplate().queryForList(sql);
for (Map row : rows
- java设计模式之单例模式
chicony
java设计模式
在阎宏博士的《JAVA与模式》一书中开头是这样描述单例模式的:
作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。 单例模式的结构
单例模式的特点:
单例类只能有一个实例。
单例类必须自己创建自己的唯一实例。
单例类必须给所有其他对象提供这一实例。
饿汉式单例类
publ
- javascript取当月最后一天
ctrain
JavaScript
<!--javascript取当月最后一天-->
<script language=javascript>
var current = new Date();
var year = current.getYear();
var month = current.getMonth();
showMonthLastDay(year, mont
- linux tune2fs命令详解
daizj
linuxtune2fs查看系统文件块信息
一.简介:
tune2fs是调整和查看ext2/ext3文件系统的文件系统参数,Windows下面如果出现意外断电死机情况,下次开机一般都会出现系统自检。Linux系统下面也有文件系统自检,而且是可以通过tune2fs命令,自行定义自检周期及方式。
二.用法:
Usage: tune2fs [-c max_mounts_count] [-e errors_behavior] [-g grou
- 做有中国特色的程序员
dcj3sjt126com
程序员
从出版业说起 网络作品排到靠前的,都不会太难看,一般人不爱看某部作品也是因为不喜欢这个类型,而此人也不会全不喜欢这些网络作品。究其原因,是因为网络作品都是让人先白看的,看的好了才出了头。而纸质作品就不一定了,排行榜靠前的,有好作品,也有垃圾。 许多大牛都是写了博客,后来出了书。这些书也都不次,可能有人让为不好,是因为技术书不像小说,小说在读故事,技术书是在学知识或温习知识,有
- Android:TextView属性大全
dcj3sjt126com
textview
android:autoLink 设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接。可选值(none/web/email/phone/map/all) android:autoText 如果设置,将自动执行输入值的拼写纠正。此处无效果,在显示输入法并输
- tomcat虚拟目录安装及其配置
eksliang
tomcat配置说明tomca部署web应用tomcat虚拟目录安装
转载请出自出处:http://eksliang.iteye.com/blog/2097184
1.-------------------------------------------tomcat 目录结构
config:存放tomcat的配置文件
temp :存放tomcat跑起来后存放临时文件用的
work : 当第一次访问应用中的jsp
- 浅谈:APP有哪些常被黑客利用的安全漏洞
gg163
APP
首先,说到APP的安全漏洞,身为程序猿的大家应该不陌生;如果抛开安卓自身开源的问题的话,其主要产生的原因就是开发过程中疏忽或者代码不严谨引起的。但这些责任也不能怪在程序猿头上,有时会因为BOSS时间催得紧等很多可观原因。由国内移动应用安全检测团队爱内测(ineice.com)的CTO给我们浅谈关于Android 系统的开源设计以及生态环境。
1. 应用反编译漏洞:APK 包非常容易被反编译成可读
- C#根据网址生成静态页面
hvt
Web.netC#asp.nethovertree
HoverTree开源项目中HoverTreeWeb.HVTPanel的Index.aspx文件是后台管理的首页。包含生成留言板首页,以及显示用户名,退出等功能。根据网址生成页面的方法:
bool CreateHtmlFile(string url, string path)
{
//http://keleyi.com/a/bjae/3d10wfax.htm
stri
- SVG 教程 (一)
天梯梦
svg
SVG 简介
SVG 是使用 XML 来描述二维图形和绘图程序的语言。 学习之前应具备的基础知识:
继续学习之前,你应该对以下内容有基本的了解:
HTML
XML 基础
如果希望首先学习这些内容,请在本站的首页选择相应的教程。 什么是SVG?
SVG 指可伸缩矢量图形 (Scalable Vector Graphics)
SVG 用来定义用于网络的基于矢量
- 一个简单的java栈
luyulong
java数据结构栈
public class MyStack {
private long[] arr;
private int top;
public MyStack() {
arr = new long[10];
top = -1;
}
public MyStack(int maxsize) {
arr = new long[maxsize];
top
- 基础数据结构和算法八:Binary search
sunwinner
AlgorithmBinary search
Binary search needs an ordered array so that it can use array indexing to dramatically reduce the number of compares required for each search, using the classic and venerable binary search algori
- 12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!
刘星宇
c面试
12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!
1.gets()函数
问:请找出下面代码里的问题:
#include<stdio.h>
int main(void)
{
char buff[10];
memset(buff,0,sizeof(buff));
- ITeye 7月技术图书有奖试读获奖名单公布
ITeye管理员
活动ITeye试读
ITeye携手人民邮电出版社图灵教育共同举办的7月技术图书有奖试读活动已圆满结束,非常感谢广大用户对本次活动的关注与参与。
7月试读活动回顾:
http://webmaster.iteye.com/blog/2092746
本次技术图书试读活动的优秀奖获奖名单及相应作品如下(优秀文章有很多,但名额有限,没获奖并不代表不优秀):
《Java性能优化权威指南》