java核心技术(卷I)[接口|lambda|内部类|异常|泛型] 精华版

10 篇文章 1 订阅

java核心技术系列

java核心技术(卷I)[概述|结构|对象|继承] 精华版

java核心技术(卷I)[接口|lambda|内部类|异常|泛型] 精华版

java核心技术(卷I)[集合|并发] 精化版


java核心技术 卷I
._ 接口
. ._ 概念
. . ._ 接口不是类,是对类的一组需求描述,这些类要遵从接口描述的统一格式定义
. . . public interface Comparable
. . . {
. . .     int compareTo(Object other); 
. . . }
. ._ 实现
. . . 要将类声明为实现某一个接口,需要使用关键字implements
. . . class Employee implements Comparable
. . ._ 在实现接口时,必须把方法声明为public,否则,编译器将认为这个方法的访问属性是包可见性。
. ._ 特性
. . ._ 接口可以被扩展,允许存在多条从具有较高通用型的接口到较高专用性的接口的链
. . ._ 虽然接口中不能包含实例域或静态方法,但是可以包含常量
. . ._ 接口中的域自动被设为public static final
. . ._ 尽管每个类只能够有一个超类,但是可以实现多个接口,这为类定义行为提供了极大的灵活性
. ._ 与抽象类
. . ._ 每个类只能扩展一个类,但每个类可实现多个接口
. . ._ 与多重继承相比,接口可以提供多重继承的大多数好处,同时还能避免多重继承的复杂性和低效性
. ._ 静态方法
. . ._ 允许在接口中增加静态方法,但这有违于接口作为抽象规范的初衷
. . ._ 通常的做法是将静态方法放在伴随类中
. . ._ 在javaAPI中,有很多接口都有相应的伴随类,这个伴随类中实现了相应接口的部分或所有方法,如Collection/AbstractCollection
. ._ 默认方法
. . . 可以为接口方法提供一个默认实现,必须用default修饰符标记这样一个方法
. . . public interface Comparable<T>
. . . {
. . .   default int compartTo(T other) {return 0;}
. . . }
. . ._ 默认方法的一个重要用法是"接口演化"
. ._ 解决默认方法冲突
. . . 如果现在一个接口中将一个方法定义为默认方法,然后又在超类或另一个接口中定义了同样的方法,java解决二义性的规则
. . . 1.超类优先:如果超类中定义了这样的方法,子类中的将被忽略
. . . 2.接口冲突:如果超类接口提供了默认方法,另一个接口提供了一个同名且参数类型相同的方法,必须覆盖这个方法类解决冲突。
. . ._ 如果两个接口定义了相同的方法,如果至少有一个接口提供了一个实现,编译器就会报错,程序员必须解决这个二义性
. . ._ 如果一个类扩展了一个超类,同时实现了一个接口,并从超类和接口继承了相同的方法,这种情况下,只会考虑超类方法,接口的所有默认方法都会被忽略,这正是“类优先”规则
. ._ 接口示例
. . ._ 回调
. . . . public static void main(Stirng[] args)
. . . . {
. . . .   ActionLIstener listener = new TimePrinter();
. . . .   Timer t = new Timer(1000, listener);
. . . .   t.start();
. . . .   JOptionPane.showMessageDialog(null, "Quit program");
. . . .   System.exit(0);
. . . . }
. . . . class TimePrinter implements ActionListener
. . . . {
. . . .   public void actionPerformed(ActionEvent event)
. . . .   {
. . . .      System.out.println("At the tone, the time is " + new Date());
. . . .      Toolkit.getDefaultTookit().beep();
. . . .   }
. . . . }
. . ._ Comparator接口
. . . . public interface Comparator<T>
. . . . {
. . . .   int compare(T first, T second);
. . . . }
. . . . class LengthComparator implements Comparator<String>
. . . . {
. . . .   public int compare(String first, String second) {
. . . .     return first.length() - second.length();
. . . .   }
. . . . }
. . . . Comparator接口包含很多方便的静态方法来创建比较器
. . . . 静态comparing方法取一个“键提取器”函数
. . . . Arrays.sort(people, Compartor.comparing(Person::getName));
. . . . 可以把比较器与thenComparing方法串起来
. . . . Arrays.sort(people, Compartor.comparing(Person::getName))
. . . . .thenComparing(Person::getFirstName)
. . . . 这些方法有很多变体,可以为comparing和thenCompariing方法提取的键指定一个比较器
. . . . Arrays.sort(people, Comparator.comparing(Person::getName,
. . . . (s,t) -> Integer.compare(s.length(), t.length())))
. . . . 另外,comparing和thenComparing方法都有很多变体形式
. . . . Arrays.sort(people, Comparator.comparingInt(p -> p.getName.length()));
. . . . 如果键函数可以返回null,可能就要用到nullsFirst和nullsLast适配器
. . . . Comparator.comparing(Person::getMiddleName(),Comparator.nullsFirst(...));
. . . . naturalOrder方法可以为任何实现了Comparable的类建立一个比较器
. . . . Arrays.sort(people, comparing(Person::getMiddleName, nullsFirst(naturalOrder())));
. . . . 静态reverseOrder方法会提供自然顺序的逆序
. . ._ 对象克隆
. . . ._ Cloneable接口与接口的正常使用没有关系,它没有指定clone方法,该方法是从Object继承过来的
. . . . Cloneable接口是java提供的一组标记接口之一,标记接口不包含任何方法,它的唯一作用就是允许在类型查询中使用instanceof
. . . . 建议自己的程序中不要使用标记接口
. . . . class Employee implements Cloneable
. . . . {
. . . .   public Employee clone() throws CloneNotSupportedException
. . . .   {
. . . .     Employee cloned = (Employee)super.clone();
. . . .     cloned.hireDay = (Date)hireDay.clone();
. . . .     return cloned;
. . . .   }
. . . . }
. ._ 小贴士
. . ._ 接口中所有的方法自动地属于public,因此不必提供public关键字
. . ._ 接口中决不能含有实例域
. ._ 代理
. . ._ 利用代理可以在运行时创建一个实现了一组给定接口的新类。这种功能只有在编译时无法确定需要实现哪个接口时才有必要时使用。
. . ._ 创建代理对象
. . . ._ 一个类加载器
. . . ._ 一个Class对象数组,每个元素都需要实现的接口
. . . ._ 一个调用处理器
. . ._ 使用代理的原因
. . . ._ 路由对远程服务器的方法调用
. . . ._ 在程序运行期间,将用户接口事件与动作关联起来
. . . ._ 为调试,跟踪方法调用
. . ._ 示例
. . . . class TraceHandler implements InvocationHandler
. . . . {
. . . .   private Object target;
. . . .   public TraceHandler(Object t)
. . . .   {
. . . .     target = t;
. . . .   }
. . . .   public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
. . . .   {
. . . .     return m.invoke(target, args);
. . . .   }
. . . . }
. . . . Object value = . . .;
. . . . InvocationHandler handler = new TraceHandler(value);
. . . . Class[] interfaces = new Class[] {Comparable.class};
. . . . Object proxy = Proxy.newProxyInstance(null, interface, handler);
. . ._ 特性
. . . ._ 代理类是在程序运行过程中创建的
. . . ._ 所有代理类都扩展于Proxy类,一个代理类只有一个实例域,即调用处理器。
. . . ._ 所有代理类都覆盖了Object类中的方法toString,equals,hashCode
. . . ._ 没有定义代理类的名字,虚拟机中的Proxy类将生成一个以字符串$Proxy开头的类名。
. . . ._ 对于特定的类加载器和预设的一组接口来说,只能有一个代理类。如果使用同一个类加载器和接口数组调用两次newProxyInstance方法的话,那么只能够得到同一个类的两个对象,也可以利用getProxyClass方法获得这个类
. . . ._ 代理类一定是public和final,如果代理类实现的所有接口都是public,代理类就不属于某个特定的包,否则,所有非公有的接口都必须属于同一个包,同时代理类也属于这个包
. . ._ api
. . . ._ InvocationHanlder
. . . . ._ Object invoke(Object porxy, Method method, Object[] args)
. . . ._ Proxy
. . . . ._ static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces)
. . . . ._ static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler)
. . . . ._ static boolean isProxyClass(Class<?> cl)
._ lambda表达式
. ._ 概念
. . ._ lambda表达式是一个可传递的代码块,可以在以后执行一次或多次
. ._ 语法
. . ._ 参数,箭头(->)以及一个表达式
. . . (String first, String second) ->
. . . {
. . .   if (first.length() < second.length()) return -1;
. . .   else if (first.length() > second.length()) return 1;
. . .   else return 0;
. . . }
. . . 即使lambda表达式没有参数,仍然要提供空括号
. . . () -> {for (int i = 100; i >= 0; i ++) System.out.println(i)}
. . . 如果可以推导出一个lambda表达式的参数类型,则可以忽略器类型
. . . Comparator<String> comp = (first, second) 
. . . -> first.length() - second.length(); 
. . . 如果方法只有一个参数,而且这个参数的类型可推导得出,那么甚至可以省略小括号
. . . ActionListener listener = event ->
. . .   System.out.println("The time is " + new Date());
. . ._ 无需指定lamdba表达式的返回类型,lambda的返回类型总是从上下文中推导得出的。
. ._ 函数式接口
. . ._ 对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式,这种接口称为函数式接口
. . ._ 最好把lambda表达式看做是一个函数,而不是一个对象,另外要接受lambda表达式可以传递到函数式接口
. . ._ 在java中,对lambda表达式所能做的也只是能转换为函数式接口
. . ._ 常用的函数式接口
. . . ._ Runnable
. . . ._ Supplier<T>
. . . ._ Consumer<T>
. . . ._ BiConsumer<T,U>
. . . ._ Function<T,R>
. . . ._ BiFuntion<T,U,R>
. . . ._ UnaryOperator<T>
. . . ._ BinaryOperator<T>
. . . ._ Predicate<T>
. . . ._ BiPredicate<T,U>
. . ._ 基本类型的函数式接口
. . . ._ BooleanSupplier
. . . ._ PSupplier
. . . ._ PConsumer
. . . ._ ObjPConsumer<T>
. . . ._ PFunction<T>
. . . ._ PToQFunction
. . . ._ ToPFunctiion<T>
. . . ._ ToPBiFunction<T,U>
. . . ._ PUnaryOperator
. . . ._ PBinaryOperator
. . . ._ PPredicate
. ._ 方法引用
. . ._ Timer t = new Timer(1000, System.out::println);
. . ._ 表达式System.out::println是一个方法引用,它等价于lambda表达式x -> System.out.println(x)
. . ._ 使用情况
. . . ._ object::instanceMethod
. . . ._ Class::staticMethod
. . . ._ Class::instanceMethod
. ._ 构造器引用
. . . ArrayList<String> names = . . .;
. . . Stream<Person> stream = names.stream.map(Person::new);
. . ._ Person::new是构造器的一个引用
. . ._ java中无法构造泛型类型T的数组,但是通过构造器引用则可实现
. ._ 变量作用域
. . ._ 你可能希望能够在lambda表达式中访问外围方法或类中的变量
. . ._ 闭包:在java中,lambda表达式就是闭包
. . ._ lambda表达式可以捕获外围作用域中变量的值,但只能引用值不会改变的变量
. . ._ lamdba表达式中捕获的变量必须实际上是最终变量,即这个变量在初始化后就不会再为它赋新值
. . ._ lambda表达式的体与嵌套快有相同的作用域
. . ._ 在lambda表达式中使用this关键字时,是指创建这个lambda表达式的方法的this参数
._ 内部类
. ._ 原因
. . ._ 内部类方法可以访问该类定义所在作用域中的数据,包括私有的数据
. . ._ 内部类可以对同一个包中的其他类隐藏起来
. . ._ 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷
. ._ 特性
. . ._ 内部类有一个隐式引用,它引用了实例化该内部对象的外围类对象,通过这个指针,可以访问外围类对象的全部状态
. ._ 示例
. . . public class TalkingClock
. . . {
. . .   private int interval;
. . .   private boolean beep;
. . .   public TalkingClock(int interval, boolean beep) {...}
. . .   public void start() {...}
. . .   public class TimPrinter implements ActionListener
. . .   {
. . .     . . .
. . .   }
. . . }
. ._ 语法规则
. . . 外围类引用:OuterClass.this
. . . public void actionPerformed(ActionEvent event)
. . . {
. . .   if (TalkingClock.this.beep) Toolkit.getDefaultToolkit().beep();
. . . }
. . . 内部类对象的构造器:outerObject.new.InnerClass(construction parameters)
. . . ActionLIstener listener = this.new.TimerPrinter();
. . ._ 内部类中声明的所有静态域都必须是final
. . ._ 对于每个外部对象,会分别有一个单独的内部类实例
. . ._ 内部类不能有static方法
. ._ 小贴士
. . . 内部类是一种编译器现象,与虚拟机无关。
. . . 编译器将会把内部类翻译成$分隔外部类名与内部类名的常规类文件,如TalkingClock$TimePrinter.class
. . ._ 由于内部类具有访问特权,所以与常规类比较起来功能更强大
. . ._ 从安全上考虑:如果内部类访问了私有数据,就有可能通过附加在外围类所在包中的其他类访问它们,但做这些事情需要高超的技巧和极大的决心。程序员不可能无意之中就获得对类的访问权限,而必须刻意地构建或修改类文件才有可能达到这个目的。
. ._ 局部内部类
. . . public void start()
. . . {
. . .   class TimePrinter implements ActionLinstener
. . .   {
. . .      public void actionPerformed(ActionEvent event)
. . .      {
. . .         System.out.println("At the tone, the time is " + new Date());
. . .         if (beep) Toolkit.getDefaultToolkit().beep();
. . .      }
. . .   }
. . .   ActionListener listener = new TimePrinter();
. . .   Timer t = new Timer(interval, listener);
. . .   t.start();
. . . }
. . ._ 局部内部类不能用public或private访问说明符进行声明
. . ._ 局部类有一个优势,即对外部世界可以完全地隐藏起来
. . ._ 局部类还可以访问局部变量,不过这些局部变量必须事实上为final
. ._ 匿名内部类
. . . new SuperType(construction parameters)
. . . {
. . .    inner class methods and data
. . . }
. . . new InterfaceType()
. . . {
. . .   methods and data
. . . }
. . . public void start()
. . . {
. . .   ActionListener listener = new TimePrinter();
. . .   Timer t = new Timer(interval, event ->
. . .       {
. . .          System.out.println("At the tone, the time is " + new Date());
. . .         if (beep) Toolkit.getDefaultToolkit().beep();
. . .       }
. . .    );
. . .   t.start();
. . . }
. . . 技巧:双括号初始化
. . . invite(new ArrayList<String>()  {{ add("Harry"); add("Tony"); }})
. ._ 静态内部类
. . . 在内部类不需要访问外围类对象的时候,应该使用静态内部类
. . . 静态内部类可以有静态域和方法
. . . 声明在接口中的内部类自动成为static和public类
. . . class ArrayAlg
. . . {
. . .   public static class Pair
. . .   { 
. . .      . . .
. . .   }
. . .   . . .
. . . }
. 异常
. 断言
. 日志
. ._ 处理错误
. . ._ 异常分类
. . . ._ Throwable
. . . . ._ Error
. . . . . ._ java运行时系统的内部错误和资源耗尽错误
. . . . . ._ 应用程序不应该抛出这种类型的对象
. . . . ._ Exception
. . . . . ._ 派生于RuntimeException
. . . . . . ._ 错误的类型转换
. . . . . . ._ 数组访问越界
. . . . . . ._ 访问null指针
. . . . . ._ 不派生于RuntimeException
. . . . . . ._ 试图在文件尾部后面读取数据
. . . . . . ._ 试图打开一个不存在的文件
. . . . . . ._ 试图根据给定的字符串查找Class对象,而这个字符串表示的类不存在
. . ._ 声明受查异常
. . . ._ 方法应该在其首部声明所有可能抛出的异常
. . . ._ public FileInputStream(String name) throws FileNotFoundException
. . . ._ 4种情况应该抛出异常
. . . . ._ 调用一个抛出受查异常的方法
. . . . ._ 程序运行过程中发生错误,并且利用throw语句抛出一个受查异常
. . . . ._ 程序出现错误会抛出一个受查异常
. . . . ._ java虚拟机和运行时库出现内部错误
. . . ._ 对于那些可能被他人使用的java方法,应该根据异常规范在方法的首部声明这个方法可能抛出异常
. . . ._ 如果一个方法可能抛出多个异常,则必须在方法首部列出所有的异常,多个异常用逗号隔开
. . ._ 如何抛出异常
. . . ._ throw new EOFException;
. . ._ 创建异常类
. . . . class FileFormatException extends IOException
. . . . {
. . . .   . . . 
. . . . }
. ._ 捕获异常
. . . try 
. . . {
. . .   . . .
. . . } catch (IOException e) {
. . .   handler for this type
. . . }
. . ._ 捕获多个异常
. . . . try 
. . . . {
. . . .   . . .
. . . . } catch (IOException e) {
. . . .   handler for IOException
. . . . } catch (FileNotFoundException e) {
. . . .   handler for FileNotFoundException
. . . . }
. . ._ finally子句
. . . . InputStream in = new FileInputStream(. . .);
. . . . try 
. . . . {
. . . .   . . .
. . . . } catch (IOException e) {
. . . .   handler for this type
. . . . } finally {
. . . .   in.close();
. . . . }
. . . ._ 不管异常是否被捕获,finally子句都将被执行
. . ._ 带资源的try语句
. . . . try (Resource res = . . .)
. . . . {
. . . .   work with res
. . . . }
. . . . ._ try块退出时,会自动条用res.close()
. . . . try (Scanner in = new Scanner(new FileInputStream("/usr/share/dict/words")), "UTF-8")
. . . . {
. . . .   while(in.hasNext())
. . . .      System.out.println(in.next());
. . . . }
. . ._ 分析堆栈轨迹
. . . . Throwable t = new Throwable();
. . . . StackTraceElement[] frames = t.getStackTrace();
. . . . for (StackTraceElement f : frames)
. . . . {
. . . .   System.out.println(f);
. . . . }
. . ._ api
. . . ._ Throwable
. . . . ._ Throwable(Throwable cause)
. . . . ._ Throwable(String message, Throwable cause)
. . . . ._ Throwable initCause(Throwable cause)
. . . . ._ Throwable getCause()
. . . . ._ StackTraceElement[] getStackTrace()
. . . . ._ void addSuppressed(Throwable t)
. . . . ._ Throwable[] getSuppressed()
. . . ._ Exception
. . . . ._ Exception(Throwable cause)
. . . . ._ Exception(String message, Throwable cause)
. . . ._ RuntimeException
. . . . ._ RuntimeException(Throwable cause)
. . . . ._ RuntimeException(String message, Throwable cause)
. . . ._ StackTraceElement
. . . . ._ String getFileName()
. . . . ._ int getLineNumber()
. . . . ._ String getClassName()
. . . . ._ String getMethodName()
. . . . ._ boolean isNativeMethod()
. . . . ._ String toString()
. ._ 断言
. . ._ 概念
. . . ._ 断言机制允许在测试期间向代码中插入一些检查语句,当代码发布时,这些插入的检测语句将会被自动移走
. . . ._ 断言失败时致命的,不可恢复的错误
. . . ._ 断言检查只用于开发的测试阶段
. . ._ 启用禁用
. . . ._ 启用: java -enableassertions 或 java -ea
. . . ._ 禁用:java -disableassertions 或 java -da
. . . . 对于没有类加载器的系统类,要使用如下:
. . . . java -enablesystemassertion 或 java -esa
. . ._ 示例
. . . ._ assert a != null;
. . ._ api
. . . ._ ClassLoader
. . . . . void setDefaultAssertionStatus(boolean b)
. . . . . 通过类加载器启用或禁用断言
. . . . ._ void setClassAssertionStatus(String className, boolean b) 对于给定的类和内部类开启或禁用断言
. . . . ._ void setPackageAssertionStatus(String packageName, boolean b) 对于给定的包及其中的类,启用或禁用断言
. . . . . void clearAssertionStatus()
. . . . . 移去所有类和包的显式断言设置
. ._ 日志
. . ._ 基本日志
. . . ._ Logger.getGlobal().info("File->Open menu item seleted");   通过全局日志记录器记录日志
. . ._ 高级日志
. . . . 企业级日志:可自定义日志记录器
. . . . private static final Logger logger = Logger.getLogger("com.mycompany.myapp");
. . ._ 特性
. . . ._ 日志记录器是有层次的,父与子之间共享某些属性
. . . ._ 日志级别
. . . . ._ 7个日志级别
. . . . . ._ SEVERE
. . . . . ._ WARNING
. . . . . ._ INFO
. . . . . ._ CONFIG
. . . . . ._ FINE
. . . . . ._ FINER
. . . . . ._ FINEST
. . . . ._ 默认情况下,只记录前三个级别
. . . . . Level.ALL:开启所有级别的记录
. . . . . Level.OFF:关闭所有级别的记录
._ 泛型
. ._ 泛型类
. . ._ 概念
. . . ._ 泛型类就是具有一个或多个类型变量的类
. . ._ 示例
. . . . public class Pair<T>
. . . . {
. . . .   private T first;
. . . .   private T second;
. . . .   public Pair() {first = null; second = null;}
. . . .   public T getFirst() {return first;}
. . . .   public T getSecond() {return second;}
. . . . }
. ._ 泛型方法
. . ._ 概念
. . . ._ 带有类型参数的方法
. . ._ 示例
. . . . public static <T> getMiddle(T... a)
. . . . {
. . . .   return a[a.length / 2];
. . . . }
. ._ 类型变量的限定
. . ._ T绑定类型的子类型,T和绑定类型可以是类,也可以是接口
. . . ._ public static <T extends Comparable> T min(T[] a)
. . ._ 可以有一个限定,也可以有多个限定,如果用一个类做为限定,它必须是限定列表中的第一个。
. . . ._ T extends Comparable & Serializable
. ._ 泛型和虚拟机
. . ._ 特性
. . . ._ 虚拟机没有泛型类对象,所有对象都属于普通类
. . . ._ 无论何时定义一个泛型类型,都自动提供了一个相应的原始类型,原始类型的名字就是删去类型参数后的泛型类型名,擦除类型变量,并替换为限定类型
. . . ._ 原始类型用第一个限定的类型变量来替换,如果没有给定限定就用Object替换
. . . ._ class Interval<T extends Serializable & Comparable>原始类型用Serializable替换T,而编译器在必要时要向Comparable插入强制类型转换
. . ._ 翻译泛型表达式
. . . ._ 当程序调用泛型方法时,如果擦除返回类型,编译器插入强制类型转换
. . . ._ 当存取一个泛型域时也需要进行强制类型转换
. . ._ 翻译泛型方法
. . . ._ 当类型擦除与多态发生了冲突时,编译器会生成一个桥方法
. . . ._ 在虚拟机中,用参数类型和返回类型确定一个方法,因此,编译器可能产生两个仅返回类型不同的方法字节码,虚拟机能够正确地处理这一情况
. . . . java泛型的事实:
. . . . 虚拟机中没有泛型,只有普通类和方法
. . . . 所有的类型参数都用它们的限定类型替换
. . . . 桥方法被合成来保持多态
. . . . 为保持类型安全性,必要时插入强制类型转换
. ._ 约束与局限性
. . ._ 不能用基本类型实例化类型参数
. . . 不能创建参数化类型的数组
. . . 可以声明通配类型的数组,然后进行类型转换
. . ._ Varargs警告
. . . ._ 可以采用两种方法抑制这种警告,一种是为包含addAll调用的方法增加注释@SuppressWarnings("unchecked"),还可以用@SafeVarargs直接标注addAll方法
. . ._ 不能实例化类型变量
. . . ._ 不能用new T(...),new T[...]或T.Class这样的表达式中的类型变量
. . . . 最好的解决办法是让调用者提供一个构造表达式
. . . . Pair<String> p = Pair.makePair(String::new)
. . ._ 不能构造泛型数组
. . ._ 泛型类的静态上下文中类型变量无效
. . ._ 不能抛出或捕获泛型类的实例
. . ._ 可以消除对受查异常的检查
. . ._ 注意擦除后的冲突
. ._ 继承规则
. . ._ 无论T和S有什么关系,Pair<T>和Pair<S>没有任何关系
. . ._ 必须注意泛型与java数组之间的重要区别,可以将一个Manage[]数组赋给一个类型为Employee[]的变量
. . ._ 数组带有特别的保护,如果试图将一个低级别的雇员存储到employeeBuddies[0],虚拟机将会抛出ArrayStoreException异常
. . ._ 永远可以将参数化类型转换成一个原始类型
. . ._ 泛型类可以扩展或实现其他的泛型类
. ._ 通配符类型
. . . <? extends Employee>
. . . ? extends Employee getFirst()
. . . 类型为Employee的子类
. . . <? super Manager>
. . . ? super Manager getFirst()
. . . 类型为Manager的超类
. . ._ public static <T extends Comparable<? super T>> T min(T[] a) . . .
. . . 子类型的另一个常见用法是作为一个函数式接口的参数类型
. . . default boolean removeIf(Predicati<? super E> filter)
. . . ? getFirst()
. . . void setFirst(?)
. . . 通配符不是类型,因此,不能在编码中使用?作为一种类型,以下代码是非法的
. . . ? t = p.getFirst()
. ._ 反射和泛型
. . ._ 泛型Class类
. . . ._ T newInstance()
. . . ._ T case(Object obj)
. . . ._ T[] getEnumConstants()
. . . ._ Class<? super T> getSuperclass()
. . . ._ Constructor<T> getConstructor(Class . . . parameterTypes)
. . . ._ Constructor<T> getDeclareConstructor(Class ...parameterTypes)
. . ._ 虚拟机中的泛型类型信息
. . . . 擦除的类型仍然保留一些泛型祖先的微弱的信息
. . . . 可以使用反射api来确定:
. . . . 这个泛型方法有一个叫做T的类型参数
. . . . 这个类型参数有一个子类型限定,其自身又是一个泛型类型
. . . . 这个限定类型有一个通配符参数
. . . . 这个通配符参数有一个超类型限定
. . . . 这个泛型方法有一个泛型数组参数
. . . . 为了表达泛型类型声明,使用java.lang.reflect包提供的接口Type。这个接口包含下列子类型
. . . . Class类,描述具体类型
. . . . TypeVariable接口,描述类型变量
. . . . WildcardType接口,描述通配符
. . . . ParameterizedType接口,描述泛型类或接口类型
. . . . GenericArrayType接口,描述泛型数组
. . . ._ api
. . . . ._ Class
. . . . . ._ TypeVariable[] getTypeParameters()
. . . . . ._ Type getGenericSuperclass()
. . . . . ._ Type[] getGenericInterfaces()
. . . . ._ Method
. . . . . ._ TypeVariable[] getTypeParameters()
. . . . . ._ Type getGenericReturnType()
. . . . . ._ Type[] getGenericParameterTypes()
. . . . ._ TypeVariable
. . . . . ._ String getName()
. . . . . ._ Type[] getBounds()
. . . . ._ WildcardType
. . . . . ._ Type[] getUpperBounds()
. . . . . ._ Type[] getLowerBounds()
. . . . ._ ParameterizedType
. . . . . ._ Type getRawType()
. . . . . ._ Type[] getActualTypeArgumetns()
. . . . . ._ Type getOwnerType()
. . . . ._ GenericArrayType
. . . . . ._ Type getGenericComponoentType()


 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值