反射、注解、动态代理、JDK8新特性

妖狐艹你老母 2023-06-27 12:44 95阅读 0赞

day14【反射、注解、动态代理、JDK8新特性】

  1. 今日内容:
  2. "反射:以后我们学的所有框架底层都是由反射
  3. "注解:今天只学基本语法
  4. 设计模式: 动态代理设计模式(基本格式)
  5. JDK8的新特性

第一章.反射

1.类的加载
  1. 源文件--通过javac编译-->字节码文件---通过Java命令(通过ClassLoader)--->JVM运行
  2. 字节码文件什么时候会被加载?
  3. 当该类被使用到时就会被加载
  4. 字节码文件需要加载几次?
  5. 只需要加载一次,当前第一次使用该类时加载,以后使用到该类不需要加载
  6. "字节码文件被加载JVM方法区内存之后,JVM会干什么事?"
  7. JVM会在堆中为该字节码文件创建一个Class对象(字节码文件对象),对象中保存了字节码文件中所有的信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v7rCBuSz-1578312743688)(img/image-20200105091214510.png)]

2.什么是反射
  1. 反射是一种运行时技术,运行时获取某个类的Class对象,从而解剖它,从中获取成员变量,成员方法,构造方法等,进而可以使用他们(无论私有与否)
3.反射在实际开发中的应用
  1. a.编写IDE(集成开发环境),比如IDEA,Eclipse
  2. b.以后我们底层学习框架和设计框架都必须使用反射技术
4.反射中万物皆对象的概念
  1. 反射中万物皆对象:
  2. 字节码文件 ---> Class对象
  3. 成员变量 ---> Field对象
  4. 成员方法 ---> Method对象
  5. 构造方法 ---> Constructor对象
  6. newInstance ---> 创建对象
  7. invoke ---> 调用/执行
  8. 体验一下反射中语法:
  9. 正常语法 反射语法
  10. new 构造方法(参数); 构造方法对象.newInstance(参数);
  11. 对象名.成员方法名(参数); 成员方法对象.invoke(对象名,参数);
  12. sout(对象名.成员变量名); sout(成员变量对象.get(对象名));
  13. 对象名.成员变量名 = 成员变量对象.set(对象名,值);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kTKj6BJM-1578312743689)(img/image-20200105092106340.png)]

5.反射的第一步获取字节码文件对象(Class对象)
  1. Java提供三种方式,可以获取到Class对象
  2. /**
  3. * 获取Class对象
  4. */
  5. public class TestDemo {
  6. public static void main(String[] args) throws ClassNotFoundException {
  7. //1.通过类的静态成员来获取
  8. Class clazz1 = Cat.class;
  9. System.out.println(clazz1);
  10. //2.通过该类的某个对象,来获取Class对象
  11. Cat cc = new Cat();
  12. Class clazz2 = cc.getClass();
  13. System.out.println(clazz2);
  14. //3.通过Class类的静态方法
  15. Class clazz3 = Class.forName("com.itheima.demo02_GetClassObject.Cat");
  16. System.out.println(clazz3);
  17. //注意:以上三种是Java提供的三种方式,而不是获取三个Class对象
  18. System.out.println(clazz1 == clazz2);
  19. System.out.println(clazz1 == clazz3);
  20. System.out.println(clazz2 == clazz3);
  21. //以上三个Class对象,实际上是同一个Class对象,只是获取的方式不同而已
  22. }
  23. }
6.Class对象中的三个常见方法
  1. public String getName(); 获取全限定类名(包名.类名)
  2. public String getSimpleName(); 获取类名(不带包名)
  3. public Object newInstance(); 创建该Class对象所代表类的对象
  4. /**
  5. * Class对象的三个方法
  6. */
  7. public class TestDemo {
  8. public static void main(String[] args) throws Exception {
  9. //1.通过类的静态成员来获取
  10. Class clazz1 = Cat.class;
  11. //4.获取全限定类名
  12. System.out.println("---------------");
  13. System.out.println(clazz1.getName());
  14. //5.获取类名
  15. System.out.println(clazz1.getSimpleName());
  16. //6.创建对象(Class所代表类Cat的对象)
  17. Object obj = clazz1.newInstance();
  18. System.out.println(obj);
  19. }
  20. }
7.通过反射获取构造方法&&使用构造方法创建对象
  1. 获取构造:
  2. public Constructor getConstructor(构造方法的参数类型.class...);只能获取"public"构造
  3. public Constructor getDeclaredConstructor(构造方法的参数类型.class...);获取"任意"构造
  4. 使用构造:
  5. public Object newInstace(构造方法的实际参数);
  6. 如果是私有构造怎么使用?
  7. a.先设置该构造方法具有暴力访问权限
  8. 构造方法对象.setAccessible(true);
  9. b.然后正常使用
  10. public Object newInstace(构造方法的实际参数);
  11. /**
  12. * 通过反射获取其中的构造方法,并使用构造方法
  13. */
  14. public class TestDemo {
  15. public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
  16. //1.获取Class对象
  17. Class cc = Cat.class;
  18. //2.获取构造方法对象
  19. Constructor con1 = cc.getConstructor();
  20. System.out.println(con1);
  21. Constructor con2 = cc.getConstructor(int.class, String.class);
  22. System.out.println(con2);
  23. //如果是非公有构造,必须调用getDeclaredConstructor来获取
  24. Constructor con3 = cc.getDeclaredConstructor(String.class);
  25. System.out.println(con3);
  26. //3.通过构造方法对象就可以创建对象
  27. System.out.println("---------");
  28. Object obj1 = con1.newInstance();
  29. System.out.println(obj1);
  30. Object obj2 = con2.newInstance(10, "肥猫");
  31. System.out.println(obj2);
  32. //如果是私有构造方法,那么必须先设置暴力访问权限
  33. con3.setAccessible(true);
  34. //然后才能正常使用
  35. Object obj3 = con3.newInstance("加肥猫");
  36. System.out.println(obj3);
  37. }
  38. }
8.通过反射获取成员方法&&调用成员方法
  1. 获取成员方法:
  2. public Method getMethod("方法名",方法参数类型.class...); 获取"public"修饰成员方法
  3. public Method getDeclaredMethod("方法名",方法参数类型.class...); 获取"任意"修饰成员方法
  4. 使用成员方法:
  5. public Object invoke(对象名,执行方法需要的实际参数); -- 执行该成员方法对象
  6. 如果是私有的成员方法怎么调用呢?
  7. a.先设置暴力访问权限
  8. 成员方法对象.setAccessible(true);
  9. b.正常调用该方法即可
  10. public Object invoke(对象名,执行方法需要的实际参数); -- 执行该成员方法对象
  11. /**
  12. * 通过反射获取成员变量,并使用成员方法
  13. */
  14. public class TestDemo {
  15. public static void main(String[] args) throws Exception {
  16. //1.获取Class对象
  17. Class cc = Class.forName("com.itheima.demo04_GetMethod.Cat");
  18. //2.获取成员方法
  19. Method m1 = cc.getMethod("eat", String.class);
  20. System.out.println(m1);
  21. Method m2 = cc.getMethod("eat", String.class, String.class);
  22. System.out.println(m2);
  23. //如果成员方法是非公有的,必须通过getDeclaredMethod方法获取
  24. Method m3 = cc.getDeclaredMethod("eat");
  25. System.out.println(m3);
  26. //3.使用成员方法对象
  27. Cat cat = new Cat(10,"加菲猫");
  28. m1.invoke(cat,"鱼"); // 相当于 cat.eat("鱼")
  29. m2.invoke(cat,"鱼","啤酒");// 相当于cat.eat(鱼","啤酒");
  30. //如果是私有方法,必须先设置暴力访问权限
  31. m3.setAccessible(true);
  32. //然后调用正常调用方法
  33. m3.invoke(cat); //相当于cat.eat();
  34. }
  35. }
9.通过反射获取成员属性(了解即可)
  1. 因为成员变量都是私有的,并且有get/set方法,我们通过反射获取get/set方法就可以了!!
  2. 获取成员变量:
  3. public Field getField(String 成员变量名); -- 获取"public"成员变量
  4. public Field getDeclaredField(String 成员变量名); -- 获取"任意"成员变量
  5. 使用成员变量:
  6. "取出成员变量的值
  7. 成员变量对象.get(对象名); // 相当于 对象名.成员变量名
  8. 需要先设置暴力权限
  9. 成员变量对象.setAccessible(true);
  10. 成员变量对象.get(对象名);
  11. "修改成员变量的值
  12. 成员变量对象.set(对象名,新的值);
  13. 需要先设置暴力权限
  14. 成员变量对象.setAccessible(true);
  15. 成员变量对象.set(对象名,新的值);
10.反射中的其他方法(了解即可)
  1. 获取构造:
  2. public Constructor[] getConstructors(); -- 获取所有"public"构造
  3. public Constructor[] getDeclaredConstructors(); -- 获取所有"任意"构造
  4. 获取方法:
  5. public Method[] getMethods(); -- 获取所有"public"成员方法,包括父类继承的
  6. public Method[] getDeclaredMethods(); -- 获取所有"任意"成员方法(不包括父类继承的)
  7. 获取成员变量:
  8. public Filed[] getFields(); -- 获取所有"public"的成员变量
  9. public Filed[] getDeclaredFields(); -- 获取所有"任意"的成员变量

第二章 注解(基本语法)

1.JDK1.5新特性–注解
  1. 什么是注释:
  2. 对代码进行解释说明的文字(给程序员看)
  3. 什么是注解:
  4. 对代码进行解释说明的语法(给JVM看的,程序员也可以看)
2.注解的两个作用
  1. a.给程序带入参数(框架的时候使用)
  2. b.编译检查(在编译时期,检查我们的语法是否符合程序的要求)
  3. @Override 方法重写注解
  4. @FunctionalInterface 函数式接口注解
  5. @Deprecated 方法过期注解
  6. c.作为框架的配置文件(框架的时候使用)
3.常用两个注解介绍
  1. @author Java文件,标记作者
  2. @version Java文件,标记版本号
  3. @Override 方法重写注解
  4. @FunctionalInterface 函数式接口注解
  5. @Deprecated 方法过期注解
  6. @Test 单元测试Junit的注解
4.自定义注解
  1. 自定义类: public class 类名
  2. 自定义接口: public interface 接口名
  3. 自定义注解: public @interface 注解名
  4. 格式:
  5. public @interface 注解名{
  6. }
5.给自定义注解添加属性
  1. 格式:
  2. public @interface 注解名{
  3. //注解中只能写属性,格式: 数据类型 属性名();
  4. 数据类型 属性名() [default 默认值];
  5. 数据类型 属性名() [default 默认值];
  6. 数据类型 属性名() [default 默认值];
  7. }
  8. 注解中属性的数据类型也是有限制:
  9. a.八大基本类型
  10. b.引用类型中只能写:String,枚举,其他注解,Class
  11. c.以上12种类型的一维数组
6.自定义注解练习
  1. /**
  2. * 自定义注解
  3. */
  4. public @interface MyAnnotation {
  5. //注解的属性
  6. int age(); // default 18;
  7. String name();// default "张三";
  8. String[] hobbies();// default {"抽烟", "喝酒", "跳楼"};
  9. }
  10. /**
  11. * 使用注解格式:
  12. * @注解名(属性名=属性值,属性名=属性值,..)
  13. * 如果注解中某个属性没有默认值,那么使用该注解时必须给属性赋值,如果有默认值,可以赋值也可以不赋值
  14. */
  15. @MyAnnotation(age = 18,name = "旺财",hobbies = {
  16. "抽烟", "喝酒", "跳楼"})
  17. public class Demo {
  18. @MyAnnotation(age = 18,name = "旺财",hobbies = {
  19. "抽烟", "喝酒", "跳楼"})
  20. private String job;
  21. @MyAnnotation(age = 18,name = "旺财",hobbies = {
  22. "抽烟", "喝酒", "跳楼"})
  23. public Demo(String job) {
  24. this.job = job;
  25. }
  26. @MyAnnotation(age = 18,name = "旺财",hobbies = {
  27. "抽烟", "喝酒", "跳楼"})
  28. public void show(@MyAnnotation(age = 18,name = "旺财",hobbies = {
  29. "抽烟", "喝酒", "跳楼"}) int age) {
  30. @MyAnnotation(age = 18,name = "旺财",hobbies = {
  31. "抽烟", "喝酒", "跳楼"})
  32. String name = "";
  33. }
  34. }
7.使用注解时的注意事项
  1. a.如果注解中某个属性没有默认值,那么使用该注解时必须给属性赋值,如果有默认值,可以赋值也可以不赋值
  2. b.我们现在定义的注解,可以修饰基本上任意的地方(类上,方法上,局部变量上等...)
  3. c.我们的注解没有实际含义,注解想要有实际含义必须有注解解析器的支持
8.自定义注解中的特殊属性名value
  1. a.如果注解中只有一个属性,且属性名为value,那么使用该注解时,可以省略value直接给value赋值即可
  2. /**
  3. * 特殊的属性value
  4. */
  5. public @interface MyAnno {
  6. String value();
  7. }
  8. @MyAnno("abc") -- 此处省略value的名,直接写value的值
  9. public class Demo {
  10. }
  11. b.如果注解中有多个属性,但是有一个叫value,其他属性都有默认值,使用时可以可以省略value直接给value赋值即可
  12. /**
  13. * 特殊的属性value
  14. */
  15. public @interface MyAnno {
  16. String value();
  17. int age() default 20;
  18. }
  19. @MyAnno("abc") -- 此处省略value的名,直接写value的值,age不需要赋值
  20. public class Demo {
  21. }
9.注解的注解–元注解
  1. 元注解: 修饰注解的注解,称为元注解
  • 两个元注解

    1. @Target 元注解,修饰普通的注解
    2. 其作用是,规定普通的注解使用的目标:具体的使用目标,可以是以下几种
    3. ElementType.TYPE 表示作用目标必须是类上或者接口上
    4. ElementType.FIELD 表示作用目标必须是成员变量上
    5. ElementType.METHOD 表示作用目标必须是成员方法上
    6. ElementType.PARAMETER 表示作用目标必须是方法参数上
    7. ElementType.CONSTRUCTOR 表示作用目标必须是构造方法上
    8. ElementType.LOCAL_VARIABLE 表示作用目标必须是局部变量上
    9. /**
    10. * 使用@Target元注解,修饰普通的注解
    11. * 作用:规定普通注解使用的目标
    12. */
    13. //@Target(ElementType.TYPE) 表示作用目标必须是类上或者接口上
    14. //@Target(ElementType.FIELD) 表示作用目标必须是成员变量上
    15. //@Target(ElementType.METHOD) 表示作用目标必须是成员方法上
    16. //@Target(ElementType.CONSTRUCTOR) 表示作用目标必须是构造方法上
    17. //@Target(ElementType.PARAMETER) 表示作用目标必须是方法参数上
    18. //@Target(ElementType.LOCAL_VARIABLE) 表示作用目标必须是局部变量上
    19. @Target({
    20. ElementType.FIELD,ElementType.METHOD}) 表示作用目标必须是成员变量和成员方法上
    21. public @interface Anno1 {
    22. }
    23. @Retension 元注解,修饰普通的注解
    24. 其作用是,规定普通注解的生命周期,具体的使用生命周期,可以是以下几种
    25. RetentionPolicy.SOURCE 表示我们的注解只在源码阶段存在,编译成字节码后删除
    26. RetentionPolicy.CLASS 表示我们的注解在源码和字节码阶段都存在,运行时删除
    27. RetentionPolicy.RUNTIME 表示我们的注解一直存在
    28. /**
    29. * 使用@Retension元注解,修饰普通的注解
    30. * 作用:规定普通注解的生命周期
    31. */
    32. //@Retention(RetentionPolicy.SOURCE) 表示我们的注解只在源码阶段存在,编译成字节码后删除
    33. //@Retention(RetentionPolicy.CLASS) 表示我们的注解在源码和字节码阶段都存在,运行时删除
    34. @Retention(RetentionPolicy.RUNTIME) 表示我们的注解一直存在
    35. public @interface Anno2 {
    36. }
10.注解的解析
  1. 就是通过代码,读取某个位置上注解的属性值
  2. 注解解析的固定步骤:
  3. a.获取注解所在的Class对象
  4. b.获取注解所在的具体目标(Field,Method,Constructor)
  5. c.判断目标是否真的有此注解
  6. d.从目标上获取我们要的注解
  7. e.从注解上获取其各个属性值
  8. /**
  9. * 自定义注解:书注解
  10. */
  11. @Retention(RetentionPolicy.RUNTIME) -- 设置Book注解的生命周期是一直存在
  12. public @interface Book {
  13. String name();
  14. double price();
  15. int pages();
  16. String[] authors();
  17. }
  18. public class Pig {
  19. private int age;
  20. public Pig(int age) {
  21. this.age = age;
  22. }
  23. @Book(name = "三国演义",price = 199.99,pages = 1001,authors = {
  24. "曹雪芹","罗贯中","吴承恩","施耐庵"})
  25. public void eat() {
  26. }
  27. }
  28. public class TestDemo {
  29. public static void main(String[] args) throws NoSuchMethodException {
  30. // 注解解析的固定步骤:
  31. // a.获取注解所在的Class对象
  32. Class pigClass = Pig.class;
  33. // b.获取注解所在的具体目标(Field,Method,Constructor)
  34. Method eatMethod = pigClass.getMethod("eat");
  35. // c.判断目标是否真的有此注解
  36. boolean b = eatMethod.isAnnotationPresent(Book.class);
  37. if (b) {
  38. // d.从目标上获取我们要的注解
  39. Book book = eatMethod.getAnnotation(Book.class);
  40. // e.从注解上获取其各个属性值
  41. System.out.println("书名:" + book.name());
  42. System.out.println("价格:" + book.price());
  43. System.out.println("页数:" + book.pages());
  44. System.out.println("作者们:" + Arrays.toString(book.authors()));
  45. } else {
  46. System.out.println("该方法上没有此注解");
  47. }
  48. }
  49. }
11.综合练习_模拟Junit的@Test注解
  1. 需求: 编写一个注解,模拟Junit@Test注解功能(使用main方法来代替右键执行)
  2. /**
  3. * 自定义注解,模拟Junit的@Test注解
  4. */
  5. @Target(ElementType.METHOD)
  6. @Retention(RetentionPolicy.RUNTIME)
  7. public @interface MyTest {
  8. }
  9. public class Demo {
  10. @MyTest
  11. public void test01() {
  12. System.out.println(11111);
  13. }
  14. @MyTest
  15. public void test02() {
  16. System.out.println(22222);
  17. }
  18. @MyTest
  19. public void test03() {
  20. System.out.println(33333);
  21. }
  22. @MyTest
  23. public void test04() {
  24. System.out.println(44444);
  25. }
  26. }
  27. public class TestDemo {
  28. public static void main(String[] args) throws Exception {
  29. //1.获取目标类的字节码文件对象
  30. Class clazz = Demo.class;
  31. //2.获取目标类上所有的成员方法
  32. Method[] methods = clazz.getMethods();
  33. //3.遍历判断
  34. for (Method method : methods) {
  35. //4.判断该方法上是否有注解
  36. if (method.isAnnotationPresent(MyTest.class)) {
  37. //5.执行该方法
  38. method.invoke(new Demo());
  39. }
  40. }
  41. }
  42. }

第三章 动态代理

1.代理模式介绍
  1. 代理设计模式:
  2. 被代理对象,没有能力或者不愿意完成某件事情,找有一个代理对象,由代理对象去完成
  3. 作用:就是对被代理对象的功能进行增强
2.动态代理概述
  1. 底层通过反射技术,动态地(在运行时,需要时)生成被代理对象的代理对象
3.案例引出
  1. /**
  2. * 学校提供的教师服务
  3. */
  4. public interface SchoolService {
  5. String login(String loginName, String passWord);
  6. String getAllClazzs();
  7. }
  8. /**
  9. * 学校提供的教师服务的实现类
  10. */
  11. public class SchoolServiceImpl implements SchoolService {
  12. /**
  13. * 登录服务
  14. */
  15. @Override
  16. public String login(String loginName, String passWord) {
  17. try {
  18. Thread.sleep(new Random().nextInt(5000));
  19. } catch (InterruptedException e) {
  20. e.printStackTrace();
  21. }
  22. return "恭喜您,登录成功...";
  23. }
  24. /**
  25. * 查询班级服务
  26. */
  27. @Override
  28. public String getAllClazzs() {
  29. try {
  30. Thread.sleep(new Random().nextInt(5000));
  31. } catch (InterruptedException e) {
  32. e.printStackTrace();
  33. }
  34. return "1班,2班,3班";
  35. }
  36. }
  37. public class TestDemo {
  38. public static void main(String[] args) {
  39. //1.创建一个实现类对象
  40. SchoolServiceImpl service = new SchoolServiceImpl();
  41. //2.登录
  42. String result = service.login("laowang123", "gebi123");
  43. System.out.println(result);
  44. //3.查询班级
  45. String allClazzs = service.getAllClazzs();
  46. System.out.println(allClazzs);
  47. }
  48. }
4.使用动态代理优化代码
  1. public class TestDemo {
  2. public static void main(String[] args) {
  3. //1.为学校的服务实现类,创建一个动态代理
  4. /**
  5. * Java提供创建代理对象的方法
  6. * Proxy.newProxyInstance(
  7. * 参数1:当前类的类加载器 基本上固定: 当前类.class.getClassLoader()
  8. * 参数2:被代理对象所有实现的接口字节码对象数组 new Class[]{接口1.class,接口2.class..}
  9. * 参数3:处理接口的实现类对象(处理类对象)
  10. * );
  11. */
  12. SchoolService serviceProxy = (SchoolService)Proxy.newProxyInstance(TestDemo.class.getClassLoader(), new Class[]{
  13. SchoolService.class}, new InvocationHandler() {
  14. /**
  15. * 当我们调用动态代理对象的方法时,动态代理对象,会通过反射,把调用的方法,以及方法的参数封装起来
  16. * @param proxy 其实就是代理对象
  17. * @param method 通过代理对象调用的方法
  18. * @param args 通过带俩对象调用方法时传入的参数
  19. * @return
  20. * @throws Throwable
  21. */
  22. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  23. long start = System.currentTimeMillis();
  24. Object result = method.invoke(new SchoolServiceImpl(),args);
  25. long end = System.currentTimeMillis();
  26. System.out.println("耗时:"+(end-start)+"毫秒");
  27. return result;
  28. }
  29. });
  30. //2.调用动态代理对象的方法
  31. // String result = serviceProxy.login("1111", "2222");
  32. // System.out.println(result);
  33. //
  34. String allClazzs = serviceProxy.getAllClazzs();
  35. System.out.println(allClazzs);
  36. }
  37. }

第四章 JDK8新特性

  1. Lambda
  2. Stream
1. 方法引用
  • 方法引用介绍

    1. 允许开发者可以直接引用现有的方法,来代理函数式接口的匿名内部类(Lambda)
  • 方法引用四种方式

    1. a.通过对象名,引用对象中成员方法
    2. 对象名::成员方法名
    3. b.通过类名,直接引用类中的静态方法
    4. 类名::静态方法名
    5. c.引用类的构造器
    6. 类名::new
    7. d.引用数组的构造器
    8. 数据类型[]::new
  • 基于静态方法引用的代码演示

    1. public class TestDemo {
    2. public static void main(String[] args) {
    3. //调用方法
    4. // method(new 接口的实现类对象());
    5. // method(new Consumer<String>() {
    6. // @Override
    7. // public void accept(String s) {
    8. // System.out.println(s);
    9. // }
    10. // });
    11. // method(s -> System.out.println(s));
    12. //使用方法引用
    13. method(System.out::println);
    14. //回顾:
    15. Stream<String> stream = Stream.of("jack", "rose", "tom", "jerry");
    16. // stream.forEach(new Consumer<String>() {
    17. // @Override
    18. // public void accept(String s) {
    19. // System.out.println(s);
    20. // }
    21. // });
    22. // stream.forEach(s -> System.out.println(s));
    23. stream.forEach(System.out::println);
    24. }
    25. public static void method(Consumer<String> con) {
    26. con.accept("java");
    27. }
    28. }
2. Base64
  • Base64介绍

    1. 一种编码技术
  • Base64内嵌类和方法描述

    1. Base64.EnCoderBase64.DeCoder
    2. Base64.MimeEnCoderBase64.MimeDeCoder
    3. Base64.URLEnCoderBase64.URLDeCoder
  • Base64代码演示

    1. public class Base64Demo {
    2. public static void main(String[] args) {
    3. //1.EnCoder和DeCoder
    4. Base64.Encoder encoder = Base64.getEncoder();
    5. String encodeToString = encoder.encodeToString("中国HelloWorld我爱你".getBytes());
    6. System.out.println("编码之后的字符串:"+encodeToString);
    7. Base64.Decoder decoder = Base64.getDecoder();
    8. byte[] bs = decoder.decode(encodeToString);
    9. System.out.println("解码之后的字符串:" + new String(bs));
    10. System.out.println("--------------");
    11. //2.MIME类型编码和解码
    12. String encodeToString1 = Base64.getMimeEncoder(4,"-".getBytes()).encodeToString("中国HelloWorld我爱你".getBytes());
    13. System.out.println("编码之后的字符串:"+encodeToString1);
    14. byte[] bs1 = Base64.getMimeDecoder().decode(encodeToString1);
    15. System.out.println("解码之后的字符串:" + new String(bs1));
    16. //3.URLEnCoder和URLDeCoder
    17. System.out.println("--------------");
    18. byte[] bs2 = Base64.getUrlEncoder().encode("http://www.itheima.com".getBytes());
    19. System.out.println("编码之后的字符串:"+new String(bs2));
    20. byte[] bytes = Base64.getUrlDecoder().decode(bs2);
    21. System.out.println("解码之后的字符串:"+new String(bytes));
    22. //UUID 生成一个32个长度的全球唯一字符串
    23. UUID uuid = UUID.randomUUID();
    24. System.out.println(uuid);
    25. }
    26. }
总结
  1. "能够通过反射技术获取Class字节码对象
  2. "能够通过反射技术获取构造方法对象,并创建对象。
  3. "能够通过反射获取成员方法对象,并且调用方法。
  4. 能够通过反射获取属性对象,并且能够给对象的属性赋值和取值。
  5. "能够说出注解的作用
  6. 编译检查
  7. "能够自定义注解和使用注解
  8. public @interface 注解名{
  9. 数据类型 属性名();
  10. 数据类型只能是三大类: 基本类型,四个引用类型(String),以上12个一维数组
  11. }
  12. @注解名(属性名="具体的值",....)
  13. 特殊value
  14. 能够说出常用的元注解及其作用
  15. @Target
  16. @Rentetion
  17. "能够解析注解并获取注解中的数据
  18. a.获取Class
  19. b.获取具体对象(Method,Constructor,Field)
  20. c.判断 isAnnotaionPresent(注解名.class);
  21. d.取出 getAnnotaion(注解名.class);
  22. e.获取注解中的属性值 注解对象.属性名();
  23. 能够完成注解的MyTest案例
  24. 能够说出动态代理模式的作用
  25. 能够使用Proxy的方法生成代理对象
  26. 能够使用四种方法的引用(建议观看课后扩展视频_方法引用完整版)
  27. 能够使用Base64对基本数据、URLMIME类型进行编解码

发表评论

表情:
评论列表 (有 0 条评论,95人围观)

还没有评论,来说两句吧...

相关阅读

    相关 jdk8特性

    在学习JDK8新特性Optional类的时候,提到对于Optional的两个操作映射和过滤设计到JDK提供的流式出来。这篇文章便详细的介绍流式处理: 一. 流式处理简介 流

    相关 JDK8 特性

    接口的默认方法只需要使用 default 关键字即可,这个特征又叫做 扩展方法 Lambda 表达式 Functional 接口 函数式接口 是指仅仅只包含一个抽象方法...