Java数据结构|String类(二)+反射枚举Lambda+泛型的进阶
所有双引号引起来的内容都会放在常量池里面
intern方法
intern该方法的作用是手动将创建的String对象添加到常量池中,也叫手动入池
注意:只能对于字符类型有用,对于字符串类型是无法拼接的
Hash底层的原码
数组table在第一次调用put方法时进行内存分配,赋值16
学习put与get的底层方法
反射
反射能在运行时获取类当中的基本信息,即使是私密的也能查看有什么
反射机制的起源---class类
对于.java程序,经过编译之后生成了.class字节码文件,最后在jvm上运行解析成一个Class对象
对于class类的方法,增加declare可以访问某个对象,例如getField只能去获得某个公有的属性对象;getDeclaredField可以获得某个属性对象(即使被private所修饰)
反射实例
获得class对象的三种方法:
第一种:使用 Class.forName("类的全路径名"); 静态方法。---最常用的方法
前提:已明确类的全路径名
第二种:使用 .class 方法
说明:仅适合在编译前就已经明确要操作的 Class
第三种:使用类对象的 getClass() 方法
反射的运用
1.通过反射创建对象
2.私有方法通过反射在类外修改封装的变量
反射优点和缺点
优点:
1. 对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法
2. 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力
3. 反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。
缺点:
1. 使用反射会有效率问题。会导致程序效率降低。
2. 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 。
总结
1. 反射的意义
2. 反射重要的几个类:Class类 、Field类、 Method类、 Constructor类
3. 学会合理利用反射,一定要在安全环境下使用。
枚举
枚举的创建
枚举的使用
首先创建好枚举之后,定义枚举对象
1、switch语句
2、常用方法
Enum 类的常用方法
(1)values()----以数组形式返回枚举类型的所有成员
(2)ordinal()----获取枚举成员的索引位置
(3)valueOf()---将普通字符串转换为枚举实例
(4)compareTo()---比较两个枚举成员在定义时的顺序
重要:枚举的构造方法默认是私有的
在创建自己的构造方法时,也要同时对之前的对象进行修改
优点:
1. 枚举常量更简单安全 。
2. 枚举具有内置方法 ,代码更优雅
缺点:
1. 不可继承,无法扩展
注意:枚举可以避免反射和序列化
Lambda表达式
函数式接口
函数式接口定义:一个接口有且只有一个抽象方法
可以通过添加@FunctionalInterface来保证函数式接口只存在一个抽象方法
Lambda的使用
正常接口本身是不能实例化的,只能通过匿名内部类来将揭开实例化(本质上是模拟一个类实现了接口),再去重写函数式接口中的方法
但通过lambda表达式
二者是等价的
带有参数的Lambda表达式
数据类型可以进行省略,数据类型不同时不能省略
Lambda表达式还可以充当比较器
正常引入比较器需要重写compare方法,而通过Lambda表达式可以大大减少代码量
语法精简
1. 参数类型可以省略,如果需要省略,每个参数的类型都要省略。
2. 参数的小括号里面只有一个参数,那么小括号可以省略
3. 如果方法体当中只有一句代码,那么大括号可以省略
4. 如果方法体中只有一条语句,且是return语句,那么大括号可以省略,且去掉return关键字。
变量捕获
匿名内部类的变量捕获
对于变量a在匿名内部类的使用,要么a是一个常量,要么a在使用前后都不能进行修改,否则会报错(在Lambda表达式中也一样,Lambda表达式本质上也是一个匿名内部类)
forEach方法
forEach方法帮助实现顺序表的遍历
sort方法
sort方法帮助排序
总结
Lambda表达式的优点很明显,在代码层次上来说,使代码变得非常的简洁。缺点也很明显,代码不易读。
泛型进阶
通配符
对于将要传入fun方法的数据类型,可能存在不确定因素,可以使用通配符来避免类型不匹配
通配符的上下界
通配符的上界,不能进行写入数据,只能进行读取数据。
fun只能传入Fruit以及其子类,父类不能传入
在接收时要遵循向上传型的原则,只能通过Fruit类型来接受
set是不成立的,因为不清楚具体是哪个子类,不能往里放元素
通配符的下界,不能进行读取数据,只能写入数据。
只能传入Fruit及Fruit类型的父类,可以set成立,因为放入的新对象都是其父类
取元素时就涉及到了向下传型,上图中的getMessage2可能获取到Food类型的数据,只有强制传型才能被通过,存在不安全因素
