关于Serializable序列化的问题
序列化简介
将实现了Serializable接口的对象转化为一个字节序列,并可以将这个序列完全恢复为原来的对象,序列化可以弥补不同操作系统之间的差异
序列化作用
Java远程方法调用
对JavaBean进行序列化
serialVersionUID
序列化和反序列化就是通过对比其SerialversionUID来进行的,一旦SerialversionUID不匹配,反序列化就无法成功
为什么用户类不序列化
避免由于类似对象引用造成的重复保存。
Transient 关键字
让某些被修饰的成员属性变量不被序列化
注意事项:
被static修饰的属性不会被序列化;
对象的类名和属性都会被序列化,方法不会被序列化;
通过网络,文件进行序列化时,必须按照写入的顺序读取对象;
反序列化需要序列化对象的class文件;
在不同的JVM之间,默认生成的SerialversionUID可能不同,有可能造成序列化失败,因此最好显式声明SerialversionUID。
Thymeleaf
简单描述
Thymeleaf是一个XML/XHTML/HTML5模板引擎,可用于Web与非Web环境中的应用开发;
Thymeleaf提供了一个用于整合Spring MVC的可选模块,在应用开发中,你可以使用Thymeleaf来完全代替JSP或其他模板引擎,如Velocity、FreeMarker等。Thymeleaf的主要目标在于提供一种可被浏览器正确显示的、格式良好的模板创建方式,因此也可以用作静态建模。你可以使用它创建经过验证的XML与HTML模板。相对于编写逻辑或代码,开发者只需将标签属性添加到模板中即可。接下来,这些标签属性就会在DOM(文档对象模型)上执行预先制定好的逻辑。
参考链接:
http://blog.didispace.com/springbootweb/
可变参数列表
形象描述
平常我们在写一个方法时,我们能确定需要传入什么样的参数以及参数的个数,这样我们在实现这个方法的时候在确定参数的时候都会有明确的目标。但是有时候会有这种特殊情况,我们并不知道我们将要传入几个参数,或者说我们并不确定外部会传入多少参数。在这种情况下,我们就要用到可变参数列表。
传入可变参数列表的方式:
一是采用传入数组的方式;
二是 int... array方式,避免构造数组
enum枚举类用法
简单描述:
有的时候一个类的对象是有限且固定的,这种情况下我们使用枚举类就比较方便;
相对优势:
枚举类更加直观,类型安全。使用常量会有以下几个缺陷:
1. 类型不安全。若一个方法中要求传入季节这个参数,用常量的话,形参就是int类型,开发者传入任意类型的int类型值就行,但是如果是枚举类型的话,就只能传入枚举类中包含的对象。
2. 没有命名空间。开发者要在命名的时候以SEASON_开头,这样另外一个开发者再看这段代码的时候,才知道这四个常量分别代表季节。
简单枚举类:
public enum SeasonEnum {
SPRING,SUMMER,FALL,WINTER;
}
1、enum和class、interface的地位一样
2、使用enum定义的枚举类默认继承了java.lang.Enum,而不是继承Object类。枚举类可以实现一个或多个接口。
3、枚举类的所有实例都必须放在第一行展示,不需使用new 关键字,不需显式调用构造器。自动添加public static final修饰。
4、使用enum定义、非抽象的枚举类默认使用final修饰,不可以被继承。
5、枚举类的构造器只能是私有的。
常见用法:
一、代表常量
二、与switch联用
三、向枚举中添加新的方法
如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 必须先定义 enum 实例。
public enum SystemType {
ERP(0,"ERP");
private int value;
private String desc;
SystemType(int value,String desc){
this.desc = desc;
this.value = value;
}
private int getValue(){
return value;
}
private String getDesc(){
return desc;
}
/**
* 通过value取枚举
*/
public static SystemType getTypeByValue(String value){
int valueKey = Integer.parseInt(value);
for (SystemType enums : SystemType.values()) {
if (enums.getValue() == valueKey) {
return enums;
}
}
return null;
}
}
四、覆盖枚举的方法
五、枚举类实现接口
六、使用接口组织枚举
七、枚举集合
参考链接:
http://blog.lichengwu.cn/java/2011/09/26/the-usage-of-enum-in-java/
ORM思想
Object Relational Mapping 对象关系映射
大概描述
把数据库的表当作类,每个记录当作类的一个实例,将类的属性与关系型数据库字段映射,用面向对象的思想来编写数据层的代码。
ORM思想的一些问题
一、数据库对Boolean类型数据的表达;
二、由于Primitive类型没有null值,Java只能使用封装类(Integer、Double等)映射数据库中为null的情况;
三、Java中只能通过基本类型来对应字段值,无法规定Unique等特征,因而较难模拟数据库中的主键和外键;
四、通过Java Object预设某Field值去取数据库记录,无法保证一定存在这样的记录;
五、在数据库中比较难映射Java中Static关键字被所有对象共享的变量。
参考链接
https://1749599512.iteye.com/blog/2223850
Enumeration与Iterator
在Java集合中,我们通常都通过 “Iterator(迭代器)” 或 “Enumeration(枚举类)” 去遍历集合。
Iterator和Enumeration区别
Enumeration源码:
public interface Enumeration<E> {
/**
* Tests if this enumeration contains more elements.
*
* @return <code>true</code> if and only if this enumeration object
* contains at least one more element to provide;
* <code>false</code> otherwise.
*/
boolean hasMoreElements();
/**
* Returns the next element of this enumeration if this enumeration
* object has at least one more element to provide.
*
* @return the next element of this enumeration.
* @exception NoSuchElementException if no more elements exist.
*/
E nextElement();
}
Iterator源码
public interface Iterator<E> {
/**
* Returns {@code true} if the iteration has more elements.
* (In other words, returns {@code true} if {@link #next} would
* return an element rather than throwing an exception.)
*
* @return {@code true} if the iteration has more elements
*/
boolean hasNext();
/**
* Returns the next element in the iteration.
*
* @return the next element in the iteration
* @throws NoSuchElementException if the iteration has no more elements
*/
E next();
/**
* Removes from the underlying collection the last element returned
* by this iterator (optional operation). This method can be called
* only once per call to {@link #next}. The behavior of an iterator
* is unspecified if the underlying collection is modified while the
* iteration is in progress in any way other than by calling this
* method.
*
*
*/
default void remove() {
throw new UnsupportedOperationException("remove");
}
/**
* Performs the given action for each remaining element until all elements
* have been processed or the action throws an exception. Actions are
* performed in the order of iteration, if that order is specified.
* Exceptions thrown by the action are relayed to the caller.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* while (hasNext())
* action.accept(next());
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
* @since 1.8
*/
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
1、函数接口不同
通过Enumeration,我们只能读取集合的数据,而不能对数据进行修改。
而Iterator除了能读取集合的数据之外,也能数据进行删除操作。
2、Iterator支持fail-fast机制,而Enumeration不支持。
Enumeration 是JDK 1.0添加的接口。使用到它的函数包括Vector、Hashtable等类,这些类都是JDK 1.0中加入的,Enumeration存在的目的就是为它们提供遍历接口。Enumeration本身并没有支持同步,而在Vector、Hashtable实现Enumeration时,添加了同步。
而Iterator 是JDK 1.2才添加的接口,它也是为了HashMap、ArrayList等集合提供遍历接口。Iterator是支持fail-fast机制的:当多个线程对同一个集合的内容进行操作时,就可能会产生fail-fast事件。
Hashtable中Iterator是通过Enumeration去实现的,而且Iterator添加了对fail-fast机制的支持。所以,Iterator执行的操作更多,速度更慢。
fail-fast机制:
即快速失败机制,是java集合(Collection)中的一种错误检测机制。
当某一个线程A通过iterator去遍历某集合的过程中,若该集合的内容被其他线程所改变了;那么线程A访问集合时,就会抛出ConcurrentModificationException异常,产生fail-fast事件。