我们在上面提到了, List> 中的元素只能使用 Object 来引用, 这样作肯定是不太方便的, 不过幸运的是, Java 的泛型机制允许我们对泛型参数的类型的上界和下界做一些限制, 例如 List extends Number> 定义了泛型的上界是 Number, 即 List 中包含的元素类型是 Number 及其子类. 而 List super Number> 定义了泛型的下界, 即 List 中包含的是 Number 及其父类. 当引入了泛型参数的上界和下界后, 我们编写代码相对来说就方便了许多, 不过也引入了新的问题, 即我们在什么时候使用上界, 什么时候使用下界, 以及它们的区别和限制到底时什么? 下面我来说说我的理解.
? extends T
? extends T 描述了通配符上界, 即具体的泛型参数需要满足条件: , 例如:
List extends Number> numberArray = new ArrayList(); // Number 是 Number 类型的
List extends Number> numberArray = new ArrayList(); // Integer 是 Number 的子类
List extends Number> numberArray = new ArrayList(); // Double 是 Number 的子类
上面三个操作都是合法的, 因为 ? extends Number 规定了泛型通配符的上界, 即我们实际上的泛型必须要是 Number 类型或者是它的子类, 而 Number, Integer, Double 显然都是 Number 的子类(类型相同的也可以, 即这里我们可以认为 Number 是 Number 的子类).
关于读取
根据上面的例子, 对于 List extends Number> numberArray 对象:
我们能够从 numberArray 中读取到 Number 对象, 因为 numberArray 中包含的元素是 Number 类型或 Number 的子类型.
同理, 我们也不能从 numberArray 中读取到 Double 类型.
关于写入
根据上面的例子, 对于 List extends Number> numberArray 对象:
我们不能添加 Number 到 numberArray 中, 因为 numberArray 有可能是List 类型
我们不能添加 Integer 到 numberArray 中, 因为 numberArray 有可能是 List 类型
我们不能添加 Double 到 numberArray 中, 因为 numberArray 有可能是 List 类型
即, 我们不能添加任何对象到 List extends T> 中, 因为我们不能确定一个 List extends T> 对象实际的类型是什么, 因此就不能确定插入的元素的类型是否和这个 List 匹配. List extends T> 唯一能保证的是我们从这个 list 中读取的元素一定是一个 T 类型的.
? super T
? super T 描述了通配符下界, 即具体的泛型参数需要满足条件: , 例如:
// 在这里, Integer 可以认为是 Integer 的 "父类"
List super Integer> array = new ArrayList();
// Number 是 Integer 的 父类
List super Integer> array = new ArrayList();
// Object 是 Integer 的 父类
List super Integer> array = new ArrayList();
关于读取
对于上面的例子中的 List super Integer> array 对象:
我们不能保证可以从 array 对象中读取到 Integer 类型的数据, 因为 array 可能是 List 类型的.
我们不能保证可以从 array 对象中读取到 Number 类型的数据, 因为 array 可能是 List 类型的.
Producer extends: 如果我们需要一个 List 提供类型为 T 的数据(即希望从 List 中读取 T 类型的数据), 那么我们需要使用 ? extends T, 例如 List extends Integer>. 但是我们不能向这个 List 添加数据.
Consumer Super: 如果我们需要一个 List 来消费 T 类型的数据(即希望将 T 类型的数据写入 List 中), 那么我们需要使用 ? super T, 例如 List super Integer>. 但是这个 List 不能保证从它读取的数据的类型.
如果我们既希望读取, 也希望写入, 那么我们就必须明确地声明泛型参数的类型, 例如 List.
例子:
public class Collections {
public static void copy(List super T> dest, List extends T> src)
{
for (int i=0; i
上面的例子是一个拷贝数据的代码, src 是 List extends T> 类型的, 因此它可以读取出 T 类型的数据(读取的数据类型是 T 或是 T 的子类, 但是我们不能确切的知道它是什么类型, 唯一能确定的是读取的类型 is instance of T), dest 是 List super T> 类型的, 因此它可以写入 T 类型或其子类的数据.
如果希望workflow存储最近20次的log,在session里的Config Object设置,log options做配置,save session log :sessions run ;savesessio log for these runs:20
session下面的source 里面有个tracing 
今天遇到一个客户BUG,当前的jdbc连接用户是root,然后部分删除操作都会报下面这个错误:The user specified as a definer ('aaa'@'localhost') does not exist
最后找原因发现删除操作做了触发器,而触发器里面有这样一句
/*!50017 DEFINER = ''aaa@'localhost' */
原来最初
O7_DICTIONARY_ACCESSIBILITY参数控制对数据字典的访问.设置为true,如果用户被授予了如select any table等any table权限,用户即使不是dba或sysdba用户也可以访问数据字典.在9i及以上版本默认为false,8i及以前版本默认为true.如果设置为true就可能会带来安全上的一些问题.这也就为什么O7_DICTIONARY_ACCESSIBIL
#h1#
0、完成课堂例子
1、将一个四位数逆序打印
1234 ==> 4321
实现方法一:
# include <stdio.h>
int main(void)
{
int i = 1234;
int one = i%10;
int two = i / 10 % 10;
int three = i / 100 % 10;
===================================================================
第一个
===================================================================
try{
CString sql;
sql.Format("select * from p