java ee进阶_JavaEE进阶集锦(持续更新中)

1.影响Servlet生命周期的注解:@PostConstruct和@PreDestroy

@PostConstruct:被修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的init()方法.注:方法会在构造函数之后,init()方法之前运行.

@PreDestroy:被修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似与Servlet的destroy()方法.注:方法会在destroy()方法之后,彻底卸载前运行.

2.JVM垃圾回收小结

Java虚拟机将堆分为新生代和老年代,并且对不同代采用不同的垃圾回收算法。其中,新生代分为Eden区和两个大小一致的Survivor区,并且其中一个Survivor区是空的(默认情况下,JVM采用一种动态分配的策略,对应VM参数为-XX:+UserPSAdaptiveSurvivorSizePolicy,根据生成对象的速率,以及Survivor区的使用情况动态调整Eden区和Survivor区的比例)。

在只针对新生代的MinorGC中,Eden区和非空Survivor区的存活对象会被复制到空的Survivor区中,当Survivor区中的存活对象复制次数超过一定数量时(对应VM参数:-XX:+MaxTenuringThreshold),那么该对象将被晋升至老年代;另外,如果单个Survivor区已经被占用了50%(对应虚拟机参数 -XX:TargetSurvivorRatio),那么较高复制次数的对象也会被晋升(promote)至老年代。

因为Minor GC只针对新生代进行垃圾回收,所以在枚举GC Roots的时候,它需要考虑从老年代到新生代的引用。为了避免扫描整个老年代,Java虚拟机引入了名为卡表(Card Table)的技术,大致的标出可能存在老年代到新生代引用的内存区域。

3.File转MultipartFile

有时候做接口测试,处理前端上传的文件,这时可采用此方法,将本地文件转为上传文件类型 MultipartFile ,代码如下:

importjava.io.File;importjava.io.FileInputStream;importorg.springframework.web.multipart.MultipartFile;importorg.springframework.mock.web.MockMultipartFile;

File pdfFile= new File("/home/nya/data/images/10000.jpg");

FileInputStream fileInputStream= newFileInputStream(pdfFile);

MultipartFile multipartFile= newMockMultipartFile(pdfFile.getName(), pdfFile.getName(),"", fileInputStream);

4.@Deprecated @SuppressWarning @Override

Java注解annotation,作为被javac识别的一种标识,此处简述三种常见注解的意义表述

@Deprecated 过时的

@SuppressWarning 抑制警告

@Override 覆盖

@Deprecated   过时API注解   我们在用到JDK提供的API的时候,在编译中遇到 这样的提示 提示用到过时的API ,那么这个API 就被这个 @Deprecated注解所 标识,在javac进行编译的时候  发现了注解便做出相应的提示 。

@SuppressWarning("deprecation")  从字面意思上就是抑制 过时API的警告 ,这个可以放在调用过时的API的方法外部或者调用方法之前,那么在编译的时候 javac遇到这个标识 即使知道API过时那么也不会输出过时API的提示

@Override 这个是覆盖注解 ,也就是在继承中进行覆盖 父类的某个方法的时候可以加上这个注解 ,加上这个注解之后 如果我们的覆盖方法 出错了 Eclipse会提示我们错误

源码示例:

参见netty源码 : io.netty.channel.ChannelInboundHandler/**

* Gets called if a {@link Throwable} was thrown.*/@Override

@SuppressWarnings("deprecation")void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;

999.代码可读性规范与优化

1、Integer的equals方法

实际开发中,基本类型的包装类使用的更多,相关的操作方法也是量级递增,这时在方法选择上 包装类 --> commons.util --> 工具类 的优先级选择顺序。

此处以两个int类型的比较为例

int a = 1;int b = 1;if ( a ==b ) ...if ( a !=b ) ...

Integer a= 2;

Integer b= 2;if( a.equals(b)) ...if ( !a.equals(b)) ...

2、stream的map使用

Java8引入的数据流Stream API,是Java在代码可读性上的一大突破。使得传统的数据流操作更加fluent。这里用作类型转换map方法愈加使得Stream调度富有变化,搭配lambda表达式更多了一种别样的美感。

而在实际使用中, -> 也推荐由 :: 替代使用,示例如下:

//基本类型转字符串

list.stream().map(item -> item.toString()).collect(Collectors.toList()); //不推荐

list.stream().map(Object::toString).collect(Collectors.toList());//本地工具类方法的调度,以数据类型转md5为例

list.stream().map(item -> Md5Utils.md5(item)).collect(Collectors.toList()); //不推荐

list.stream().map(Md5Utils::md5).collect(Collectors.toList());

注意:上例更多的适用于实体类中getXXX()的使用。***

Stream API的确给代码的编写赋予了许多便利,但一些基本的用法也是经典,一味的为了生套反而丧失了代码本身的可读性。以集合类型转换为例。

//以多线程处理常用的线程安全且多线程执行的高效队列ConcurrentLinkedDeque为例

ConcurrentLinkedDeque queue = new...;

List list = queue.stream().collect(Collectors.toList()); //尽量避免

List list = new ArrayList<>(queue);

由上可知,代码编写精炼反而赋予了更高的可读性,尽量避免脱裤子放屁,如下:

//循环中操作参数Map,为避免迭代中参数的变更,需在循环体中重新构建映射,此时只需作为带参构造获取新的Map即可

Map nowMap = new HashMap<>();

nowMap.putAll(paramMap);//避免

Map nowMap = new HashMap<>(paramMap);

你可能感兴趣的:(java,ee进阶)