动态代理,注解,

  动态代理

定义

代理:本来应该自己做的事情,请了别人来做,被请的人就是代理对象

动态代理:在程序运行过程中产生的这个对象,而程序运行过程中产生对象其实

就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理对象。

java中动态代理的使用

在Java中java.lang.reflect包下提供了一个Proxy类和一个 接口,通过使用这个类和接口就可以生成动态代理对象

public static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)

最终会调用InvocationHandler的方法

InvocationHandler Object invoke(Object proxy,Method method,Object[] args)

演示

publicstaticvoidmain(String[]args)throwsException{


    Studentstudent=newStudent();

    //创建Student的代理对象

    MyInterfacep=(MyInterface)Proxy.newProxyInstance(Student.class.getClassLoader(),Student.class.getInterfaces(),newInvocationHandler() {


        @Override

        publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{

            System.out.println("你好");

            method.invoke(student);

            returnnull;

        }

    });

    p.method();

}

原理

利用对象的类的字节码接口,写出一个新的类到本地区,通过编译器直接编译成.class文件,再通过类加载器加载进来

弊端: 代理的对象必须实现接口

cglib

定义

非java原生的动态代理, 效率更高,限制更小

可以代理没有接口的类

使用

导包

演示

publicstaticvoidmain(String[]args) {

    //导入包  cglib-core  asm    ant    ant-launcher

    //创建运行器

    MethodInterceptormi=newMethodInterceptor() {


        @Override

        publicObjectintercept(Objectarg0,Methodarg1,Object[]arg2,MethodProxyarg3)throwsThrowable{

            System.out.println("运行前");

            arg3.invokeSuper(arg0,arg2);

            System.out.println("运行后");

            returnnull;

        }

    };

    //获取代理类

    Enhancerenhancer=newEnhancer();

    //设置父类

    enhancer.setSuperclass(Demo.class);

    //运行任务

    enhancer.setCallback(mi);

    //创建代理对象

    Demod=(Demo)enhancer.create();

    d.method();

}

总结

单例模式

模式: 针对某种问题的最优解

懒汉式, 饿汉式 , 饿汉式的变形体

如何写单例模式

私有化构造方法

提供自己创建的对象给使用者

优点 :

节省内存空间,  提升访问的速度

缺点 :

相对于静态来说, 效率还是要低一些

枚举

枚举就是多例的简写形式

枚举项的权限, 修饰符, 类型, new 省略

枚举的注意事项

类加载

就是将.class文件从硬盘上读取到内存中,变成一个java可以使用的类

类加载器

四个类加载器和他们的应用范围

根类加载器不是java代码写的

双亲委派模型

加载一个类的时候,从最底层的类加载器开始逐层上传, 一直到顶层, 整个过程要检测这个类有没有被加载过

作用 : 保持类的唯一性

反射

反射其实就是java提供的另外一种编程模式

提高了代码的兼容性, 扩展性

反射操作构造方法, 操作成员变量, 操作成员方法

 default关键字

定义

1.8中允许我们给接口添加一个非抽象的方法实现, 在方法使用default关键字就可以了,这个特征又叫做拓展方法

演示

publicinterfaceMyInterface{

    //使用default的关键字

    publicdefaultvoidmethod(){

        System.out.println("你好....");

    }

}

注意事项

我们都知道, java之所以支持多实现就是应为接口中没有具体的逻辑代码, 不会造成冲突的问题, 那么1.8之后我们可以在接口中编写具体的逻辑代码了,那么多实现的时候会冲突吗 ?

肯定会冲突的,所以为了解决这个问题, 编译器要求如果多实现的时候出现了相同名称的非抽象方法的话,子类就必须重写这个方法

多实现

publicclassDemoimplementsMyInterface,MyInterface2{

    @Override

    publicvoidmethod() {

        System.out.println("子类必须重写多个接口中相同名称的非抽象方法");

MyInterface.super.method();

    }

}

二. 接口中的静态方法

定义

在接口中定义一个静态的方法, 可以有具体的代码实现

演示

publicinterfaceMyInterface{


    //静态方法 只能接口自己使用

    //接口中的静态方法权限必须是public的, 默认加上public

    staticvoidmethod3(){

        System.out.println("我是接口中的静态方法");

    }

}

注意事项

子类无法使用接口中的静态方法

接口中的静态方法的权限必须是公共的,可以不写,默认是公共的

lambda表达式

定义

一种简写形式,格式精简, 很酷

每一个lambda的表达都对应一个类型,通常是接口类型的

适用于函数式接口(只有一个抽象方法的接口)

格式

(参数...) -> {执行代码} 返回一个可用的对象

当只有一句代码时,大括号可以省略, 建议省略

演示

publicstaticvoidmain(String[]args) {

    Listlist=Arrays.asList("hh","dd","ni","kk");


    //之前的写法

    Collections.sort(list,newComparator() {

        publicintcompare(Stringo1,Stringo2) {


            returno1.compareTo(o2);

        }

    });


    //lambda表达式的写法

    Collections.sort(list, (Stringa,Stringb)->{

        returna.compareTo(b);

    });


    System.out.println(list);

}

方法的引用

使用 : : 来引用一个类的方法

publicinterfaceDoing{


    publicTdoing(Kk);

}

publicstaticvoidmain(String[]args) {

    //调用类中的静态方法来处理接口中方法上的参数

    Doingd=Integer::valueOf;

    Integerinteger=d.doing("123");

    System.out.println(integer);

}

publicstaticvoidmain(String[]args) {

    //调用对象的方法

    Doingd="java"::lastIndexOf;

    Integeri=d.doing("v");

    System.out.println(i);

}

构造方法的引用

用new关键字来代替构造方法

publicclassPerson{

    Stringname;

    Person(Stringname) {

        super();

        this.name=name;

    }

    @Override

    publicStringtoString() {

        return"Person [name="+name+"]";

    }

}

publicstaticvoidmain(String[]args) {

    //引用对象的构造方法

    Doingd=Person::new;

    Personperson=d.doing("小明");


    System.out.println(person);

}

注意事项

lambda表达式指向的接口必须和调用的方法的参数一致,也就是说相当于是接口实现类中的方法调用你指向的方法

lambda表达式中访问外层作用域和老版本的匿名对象的方式很相似, 你可以直接访问标记了final的外层局部变量, 或者示例的字段以及静态变量

lambda表达式中无法访问接口中的默认方法(就是被default修饰的方法)

四. Stream接口

定义

表示能应用在一组元素上一次执行的操作序列

其实就是找了一个地方将执行了某个方法后剩下的元素存放起来

提供了许多操作集合的方法,而且原集合数据不受影响

常用的方法

filter    过滤

sorted    排序

map    转化

match  匹配

count  计数

演示

publicstaticvoidmain(String[]args) {

    ListstringCollection=newArrayList<>();

    stringCollection.add("ddd2");

    stringCollection.add("aaa2");

    stringCollection.add("bbb1");

    stringCollection.add("aaa1");

    stringCollection.add("bbb3");

    stringCollection.add("ccc");

    stringCollection.add("bbb2");

    stringCollection.add("ddd1");


    //过滤出以a开头的元素并遍历

    stringCollection.stream().

    filter((s)->s.startsWith("a"))

    .forEach(System.out::println);;

}

并行

并行Stream可以在多个线程上同时执行

publicstaticvoidmain(String[]args) {

    intmax=1000000;

    Listvalues=newArrayList<>(max);

    for(inti=0;i

        //创建随机id

    UUIDuuid=UUID.randomUUID();

    values.add(uuid.toString());

    }


    longt1=System.nanoTime();

    //获取并行的stream

    longcount=values.parallelStream().sorted().count();

    System.out.println(count);


    longt2=System.nanoTime();

    System.out.println(t2-t1);

}

五. Date

定义

java 8 在包java.time下包含了一组全新的时间日期API

ZoneId

定义时区

publicstaticvoidmain(String[]args) {

    System.out.println(ZoneId.getAvailableZoneIds());

    //获取某个城市的时区

    ZoneIdzone1=ZoneId.of("Europe/Berlin");

    ZoneIdzone2=ZoneId.of("Asia/Shanghai");

    System.out.println(zone1.getRules());

    System.out.println(zone2.getRules());

}

LocalTime

一个没有时区信息的时间,以设置的时区为准备

publicstaticvoidmain(String[]args) {

    //获取所有的时区信息

    System.out.println(ZoneId.getAvailableZoneIds());

    //获取某个城市的时区

    ZoneIdzone1=ZoneId.of("Europe/Berlin");

    ZoneIdzone2=ZoneId.of("Asia/Shanghai");


    LocalTimenow1=LocalTime.now(zone1);

    LocalTimenow2=LocalTime.now(zone2);

    //判断时间1以是否在时间2之前

    System.out.println(now1.isBefore(now2));// true

    //使用ChronoUnit计算两个时间差值

    longhoursBetween=ChronoUnit.HOURS.between(now1,now2);

    longminutesBetween=ChronoUnit.MINUTES.between(now1,now2);

    System.out.println(hoursBetween);

    System.out.println(minutesBetween);

}

六.其他新特性

重复注解

可以将参数的名字保留到字节码中

Nashorn引擎 : jjs , 可以执行js代码

移除了FermGen空间,用Metaspace代替

-XX:MetaSpaceSize与-XX:MaxMetaspaceSize被代替-XX:PermSize与-XX:MaxPermSize

一阶段的知识点

了解计算机基础知识

了解的dos命令

了解java的历史

jdk的安装和环境变量的配置

进制

java的编译-运行方式

变量, 常量  数据类型(基本的8个,引用的5个)

运算符  :  算数运算符  复制运算符 关系运算符  逻辑运算符(双与双或/单与单或)  位运算符(& | ~  >> <<  >>>)    三元运算符

判断 循环

数组 (长度固定) 二维数组

方法  (方法的组成, 重载: 方法名相同,参数列表不同)

面向对象

如何写一个类

如何使用一个类

类和类之间的关系(重写)

抽象类和接口

多态 : 提高扩展性和兼容性

内部类 :  成员的, 静态的, 局部的, 匿名的

异常 : 最重要的时类名

常用类

Object

String (方法必须记熟)

StringBuffer  StringBuilder

Math Date SimpleDateFormat

Random  BigInteger  BigDcimal

集合

Collection Map

List Set Queue

List :

ArrayList: 查改快 增删慢  LInkedList: 增删快, 查改慢

Set

HashSet : 去重    TreeSet : 去重 排序

Map (key不能重复)

HashMap :  快    TreeMap : 排序

Collections

迭代器  迭代器运行时不能改变原集合

泛型 :

多线程

多线程的好处

多线程的创建使用

多线程的状态

线程的通信

线程池

File 类

操作本地路径(文件和文件夹)

递归

字节流 字符流 

文件流中, 除了FileInputStream和FileOutputStream之外, 其他的都是缓冲流

缓冲流有缓冲区, 使用时要注意

网络编程

ip 端口号

UDP TCP

java 两种网络编程方式(主要记TCP)

NIO

非阻塞  模拟多线程, 没有多线程的开销, 实质还是轮询处理, 只适合小流量高并发的场景

通道管理器

单例 多例  枚举 类加载器  反射  多态代理  注解   

1 . 8 新特性 :    接口中 default static的使用    la

你可能感兴趣的:(动态代理,注解,)