泛型
类、接口和方法代码可以应用于非常广泛的类型,代码与它们能够操作的数据类型不再绑定在一起,同一套代码可以用于多种数据类型,这样,不仅可以复用代码,降低耦合,而且可以提高代码的可读性和安全性。(通过使用泛型,开发环境和编译器能确保不会用错类型,为程序多设置一道安全防护网。使用泛型,还可以省去烦琐的强制类型转换,再加上明确的类型信息,代码可读性也会更好。)
泛型主要应用在java的容器类中。
泛型类型参数< T>, <U,V>
对于泛型类,Java编译器会将泛型代码转换为普通的非泛型代码,就像上面的普通Pair类代码及其使用代码一样,将类型参数T擦除,替换为Object,插入必要的强制类型转换。Java虚拟机实际执行的时候,它是不知道泛型这回事的,只知道普通的类及代码。
Java泛型是通过擦除实现的,类定义中的类型参数如T会被替换为Object,在程序运行过程中,不知道泛型的实际类型参数,比如Pair,运行中只知道Pair,而不知道Integer。
参数类型限定:
<? extends E> : ?表示通配符,<? extends E>表示有限定通配符,匹配E或E的某个子类型,具体什么子类型是未知的。用于实例化类型参数,它用于实例化泛型变量中的类型参数,只是这个具体类型是未知的,只知道它是E或E的某个子类型。 通配符:,通配符形式更为简洁。虽然通配符形式更为简洁,但上面两种通配符都有一个重要的限制:只能读,不能写。问号就是表示类型安全无知,? extends Number表示是Number的某个子类型,但不知道具体子类型,如果允许写入,Java就无法确保类型安全性,所以干脆禁止。 用于定义类型参数,它声明了一个类型参数T,可放在泛型类定义中类名后面、泛型方法返回值前面。 <? super E>,称为超类型通配符,表示E的某个父类型。有了它,我们就可以更灵活地写入了。 1)它们的目的都是为了使方法接口更为灵活,可以接受更为广泛的类型。 2)<? super E>用于灵活写入或比较,使得对象可以写入父类型的容器,使得父类型的比较方法可以应用于子类对象,它不能被类型参数形式替代。 3)<? >和<? extends E>用于灵活读取,使得方法可以读取E或E的任意子类型的容器对象,它们可以用类型参数的形式替代,但通配符形式更为简洁。 # java动态特性 应用: 动态特性的应用: - Jackson,利用反射和注解实现了通用的序列化机制。 - 有多种库(如Spring MVC、Jersey)用于处理Web请求,利用反射和注解,能方便地将用户的请求参数和内容转换为Java对象,将Java对象转变为响应内容。 - 有多种库(如Spring、Guice)利用这些特性实现了对象管理容器,方便程序员管理对象的生命周期以及其中复杂的依赖关系。 - 应用服务器(如Tomcat)利用类加载器实现不同应用之间的隔离,JSP技术利用类加载器实现修改代码不用重启就能生效的特性。 - 面向方面的编程AOP(Aspect Oriented Programming)将编程中通用的关注点(如日志记录、安全检查等)与业务的主体逻辑相分离,减少冗余代码,提高程序的可维护性, AOP需要依赖上面的这些特性来实现。 ## 反射 能够分析类能力的程序称为反射(reflective)。它是在运行时,而非编译时,动态获取类型的信息,比如接口信息、成员信息、方法信息、构造方法信息等,根据这些动态获取到的信息创建对象、访问/修改成员、调用方法等。 反射机制可以用来: ● 在运行时分析类的能力。 ● 在运行时查看对象,例如,编写一个toString方法供所有类使用。 ● 实现通用的数组操作代码。 ● 利用Method对象,这个对象很像C++中的函数指针。 反射是一种功能强大且复杂的机制。使用它的主要人员是工具构造者. 所有类的根父类Object有一个方法,可以获取对象的Class对象: public final native Class<?> getClass();java.lang.Class,Class是一个泛型类,有一个类型参数,getClass()并不知道具体的类型,所以返回Class<?>.
获取Class对象不一定需要实例对象,如果在写程序时就知道类名,可以使用<类名>.class获取Class对象: Class dt=Date.Class();
接口也有Class对象,且这种方式对于接口也是适用的.
pulic class Class<T> extends Object implements Serializable, AnnotatedElement, GenericDeclaration, Type{
//inherited from class java.lang.Object:clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
public static Class<?> forName(String ClassName){
//Returns the Class object associated with the class or interface with the given string name.
}
public static Class<?> forName(String name, boolean initialize, ClassLoader loader){
//Returns the Class object associated with the class or interface with the given string name, using the given class loader.
}
//instance methods:
//names String getName(); getSimpleName();getCanonicalName();
//field 类中定义的静态和实例变量都被称为字段
//method getMethods(); method类可以执行invoke(Object,args)方法;对invoke方法,如果Method为静态方法,obj被忽略,可以为null, args可以为null,也可以为一个空的数组,方法调用的返回值被包装为Object返回,如果实际方法调用抛出异常,异常被包装为InvocationTargetException重新抛出,可以通过getCause方法得到原异常
//创建对象实例 Map<String,Integer> m=HashMap.Class.newInstance(); map.put('a',123)
//类型检查与转换 cls.isInstance(Object obj)==instanceof
//类的声明信息
//类型信息
//classloader
}
反射的使用时机与问题:
1)反射更容易出现运行时错误,使用显式的类和接口,编译器能帮我们做类型检查,减少错误,但使用反射,类型是运行时才知道的,编译器无能为力。
2)反射的性能要低一些,在访问字段、调用方法前,反射先要查找对应的Field/Method,要慢一些。简单地说。
如果能用接口实现同样的灵活性,就不要使用反射。
注解
注解:注解就是给程序添加一些信息,用字符@开头,这些信息用于修饰它后面紧挨着的其他代码元素,比如类、接口、字段、方法、方法中的参数、构造方法等。注解可以被编译器、程序运行时和其他工具使用,用于增强或修改程序行为等。
很多配置没用注解之前是通过配置文件实现的,但配置项和要配置的程序元素不在一个地方,难以管理和维护,使用注解就简单多了,代码和配置放在一起,一目了然,易于理解和维护.
声明式的编程风格:
❑ 声明的关键字和语法本身。❑ 系统/框架/库,它们负责解释、执行声明式的语句。❑ 应用程序,使用声明式风格写程序。
interface
- why interface ?
接口本身并不能说明哪种实现的效率究竟如何。循环数组要比链表更高效,因此多数人优先选择循环数组。然而,通常这样做也需要付出一定的代价。循环数组是一个有界集合,即容量有限。如果程序中要收集的对象数量没有上限,就最好使用链表来实现。
public interface Collection<E>{
boolean add(E element);
Iterator<E> iterator();//iterator方法用于返回一个实现了Iterator接口的对象。可以使用这个迭代器对象依次访问集合中的元素。
}
public interface Iterator<E>{
E next();
boolean hasNext();
void remove();
default void forEachRemaining(Consumer<? super E> action);
/*编译器简单地将“for each”循环翻译为带有迭代器的循环。
“for each”循环可以与任何实现了Iterable接口的对象一起工作,这个接口只包含一个抽象方法:
SE8之后,提供了lambda表达式 iterator.forEachRemaining(element -> do something with element)
*/
}
Type | Description | desc | 举例 |
---|---|---|---|
<– | 继承 | Inheritance | |
*– | 组合 | Composition | contains-a的关系,这种关系比聚合更强,也称为强聚合; |
o– | 聚合 | Aggregation | 聚合是关联关系的一种特例,他体现的是整体与部分、拥有的关系,即has-a的关系 |
–> | 关联 | Association | 关联类以类属性的形式出现在关联类 |
– | Link (Solid) | ||
…> | 依赖 | Dependency | A独立,B不独立,B依赖于A,如果独立的A改变,将影响B。 |
… | > | 实现 | Realization |
… | Link (Dashed) |