
Short shortValue = (short)12345;System.out.println(shortValue == 12345); // trueInteger intValue = 12345;System.out.println(intValue == 12345); // trueLong longValue = 12345L;System.out.println(longValue == 12345); // true
Short shortValue = (short)12345;System.out.println(Objects.equals(shortValue, 12345)); // falseInteger intValue = 12345;System.out.println(Objects.equals(intValue, 12345)); // trueLong longValue = 12345L;System.out.println(Objects.equals(longValue, 12345)); // false
getstatic java.lang.System.out : java.io.PrintStream [22]aload_1 [shortValue]invokevirtual java.lang.Short.shortValue() : short [28]sipush 12345if_icmpne 24iconst_1goto 25iconst_0invokevirtual java.io.PrintStream.println(boolean) : void [32]
getstatic java.lang.System.out : java.io.PrintStream [22]aload_1 [shortValue]sipush 12345invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [28]invokestatic java.util.Objects.equals(java.lang.Object, java.lang.Object) : boolean [33]invokevirtual java.io.PrintStream.println(boolean) : void [39]
在 Java 语言中,整数的默认数据类型是 int,小数的默认数据类型是 double。
Short shortValue = (short)12345;System.out.println(shortValue == (short)12345); // trueInteger intValue = 12345;System.out.println(intValue == 12345); // trueLong longValue = 12345L;System.out.println(longValue == 12345L); // true
Short shortValue = (short)12345;System.out.println(Objects.equals(shortValue, (short)12345)); // trueInteger intValue = 12345;System.out.println(Objects.equals(intValue, 12345)); // trueLong longValue = 12345L;System.out.println(Objects.equals(longValue, 12345L)); // true
Unlikely argument type for equals(): int seems to be unrelated to ShortUnlikely argument type for equals(): int seems to be unrelated to Long
条件表达式?表达式1:表达式2boolean condition = false;Double value1 = 1.0D;Double value2 = 2.0D;Double value3 = null;Double result = condition ? value1 * value2 : value3; // 抛出空指针异常
Double result = condition ? value1 * value2 : value3;iload_1 [condition]ifeq 33aload_2 [value1]invokevirtual java.lang.Double.doubleValue() : double [24]aload_3 [value2]invokevirtual java.lang.Double.doubleValue() : double [24]dmulgoto 38aload 4 [value3]invokevirtual java.lang.Double.doubleValue() : double [24]invokestatic java.lang.Double.valueOf(double) : java.lang.Double [16]astore 5 [result]
若两个表达式类型相同,返回值类型为该类型;
若两个表达式类型不同,但类型不可转换,返回值类型为 Object 类型;
若两个表达式类型不同,但类型可以转化,先把包装数据类型转化为基本数据类型,然后按照基本数据类型的转换规则 (byte < short(char)< int < long < float < double) 来转化,返回值类型为优先级最高的基本数据类型。
if (condition) {result = value1 * value2;} else {result = value3;}
boolean condition = false;double value1 = 1.0D;double value2 = 2.0D;double value3 = 3.0D;double result = condition ? value1 * value2 : value3;
/** 分页数据VO类 */@Getter@Setter@ToString@NoArgsConstructor@AllArgsConstructorpublic class PageDataVO<T> {/** 总共数量 */private Long totalCount;/** 数据列表 */private List<T> dataList;}
/** 用户DAO接口 */@Mapperpublic interface UserDAO {/** 统计用户数量 */public Long countUser(@Param("query") UserQueryVO query);/** 查询用户信息 */public List<UserDO> queryUser(@Param("query") UserQueryVO query);}
/** 用户服务类 */@Servicepublic class UserService {/** 用户DAO */@Autowiredprivate UserDAO userDAO;/** 查询用户信息 */public PageDataVO<UserVO> queryUser(UserQueryVO query) { List<UserDO> dataList = null;Long totalCount = userDAO.countUser(query);if (Objects.nonNull(totalCount) && totalCount.compareTo(0L) > 0) {dataList = userDAO.queryUser(query);}return new PageDataVO(totalCount, dataList);}}
以上代码没有任何编译问题,但是却把 UserDO 中一些涉密字段返回给前端。细心的读者可能已经发现了,在 UserService 类的 queryUser 方法的语句 return new PageDataVO(totalCount, dataList); 中,我们把 List<UserDO> 对象 dataList 赋值给了 PageDataVO<UserVO> 的 List<UserVO> 字段 dataList。
问题是:为什么开发工具不报编译错误啦?
ArrayList list = new ArrayList();ArrayList<String> list = new ArrayList<String>();// 第一种情况ArrayList list1 = new ArrayList<String>();// 第二种情况ArrayList<String> list2 = new ArrayList();
最终的效果就是:我们神奇地把 List<UserDO>
问题的根源就是:我们在初始化 PageDataVO 对象时,没有要求强制进行类型检查。
【推荐】集合泛型定义时,在 JDK7 及以上,使用 diamond 语法或全省略。
说明:菱形泛型,即 diamond,直接使用<>来指代前边已经指定的类型。
// <> diamond 方式HashMap<String, String> userCache = new HashMap<>(16);// 全省略方式ArrayList<User> users = new ArrayList(10);
return new PageDataVO<>(totalCount, dataList);Cannot infer type arguments for PageDataVO<>/** 基础DO类 */@Getter@Setter@ToStringpublic class BaseDO<T> {private T id;private Date gmtCreate;private Date gmtModified;}
/** 用户DO */@Getter@Setter@ToStringpublic static class UserDO extends BaseDO<Long> {private String name;private String description;}
/** 用户VO类 */@Getter@Setter@ToStringpublic static class UserVO {private Long id;private String name;private String description;}
/** 用户服务类 */@Servicepublic class UserService {/** 用户DAO */@Autowiredprivate UserDAO userDAO;/** 查询用户 */public List<UserVO> queryUser(UserQueryVO query) {// 查询用户信息List<UserDO> userDOList = userDAO.queryUser(query);if (CollectionUtils.isEmpty()) {return Collections.emptyList();}// 转化用户列表List<UserVO> userVOList = new ArrayList<>(userDOList.size());for (UserDO userDO : userDOList) {UserVO userVO = new UserVO();BeanUtils.copyProperties(userDO, userVO);userVOList.add(userVO);}// 返回用户列表return userVOList;}}
[{"description":"This is a tester.","name":"tester"},...]
Object value = readMethod.invoke(source);if (Objects.nonNull(value) &&ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], value.getClass())) {... // 赋值相关代码}
/** 城市辅助类 */@Slf4jpublic class CityHelper {/** 读取城市 */public static Collection<City> readCities(String fileName) {try (FileInputStream stream = new FileInputStream(fileName);InputStreamReader reader = new InputStreamReader(stream, "GBK");CSVParser parser = new CSVParser(reader, CSVFormat.DEFAULT.withHeader())) {Set<City> citySet = new HashSet<>(1024);Iterator<CSVRecord> iterator = parser.iterator();while (iterator.hasNext()) {citySet.add(parseCity(iterator.next()));}return citySet;} catch (IOException e) {log.warn("读取所有城市异常", e);}return Collections.emptyList();}/** 解析城市 */private static City parseCity(CSVRecord record) {City city = new City();city.setCode(record.get(0));city.setName(record.get(1));return city;}/** 城市类 */@Getter@Setter@ToStringprivate static class City {/** 城市编码 */private String code;/** 城市名称 */private String name;}}
编码,名称010,北京020,广州010,北京
[{"code":"010","name":"北京"},{"code":"020","name":"广州"},{"code":"010","name":"北京"}]public native int hashCode();public boolean equals(Object obj) {return (this == obj);}
/** 城市类 */@Getter@Setter@ToStringprivate static class City {/** 城市编码 */private String code;/** 城市名称 */private String name;/** 判断相等 */@Overridepublic boolean equals(Object obj) {if (obj == this) {return true;}if (Objects.isNull(obj)) {return false;}if (obj.getClass() != this.getClass()) {return false;}return Objects.equals(this.code, ((City)obj).code);}/** 哈希编码 */@Overridepublic int hashCode() {return Objects.hashCode(this.code);}}
[{"code":"010","name":"北京"},{"code":"020","name":"广州"}]List<City> citySet = new ArrayList<>(1024);Iterator<CSVRecord> iterator = parser.iterator();while (iterator.hasNext()) {citySet.add(parseCity(iterator.next()));}return citySet;
Map<String, City> cityMap = new HashMap<>(1024);Iterator<CSVRecord> iterator = parser.iterator();while (iterator.hasNext()) {City city = parseCity(iterator.next());cityMap.put(city.getCode(), city);}return cityMap.values();
/** 用户服务类 */@Servicepublic class UserService {/** 超级用户 */private User superUser;/** 设置超级用户 */public void setSuperUser(User superUser) {this.superUser = superUser;}/** 获取超级用户 */public final User getSuperUser() {return this.superUser;}}
/** 公司服务类 */@Servicepublic class CompanyService {/** 公司DAO */@Autowiredprivate CompanyDAO companyDAO;/** 用户服务 */@Autowiredprivate UserService userService;/** 删除公司 */public void deleteCompany(Long companyId, Long operatorId) {// 设置超级用户userService.setSuperUser(new User(0L, "admin", "超级用户"));// 验证超级用户if (!Objects.equals(operatorId, userService.getSuperUser().getId())) {throw new ExampleException("只有超级用户才能删除公司");}// 删除公司信息companyDAO.delete(companyId, operatorId);}}
public class UserService$$EnhancerBySpringCGLIB$$a2c3b345 extends UserService implements SpringProxy, Advised, Factory {......public final void setSuperUser(User var1) {MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;if (var10000 == null) {CGLIB$BIND_CALLBACKS(this);var10000 = this.CGLIB$CALLBACK_0;}if (var10000 != null) {var10000.intercept(this, CGLIB$setSuperUser$0$Method, new Object[]{var1}, CGLIB$setSuperUser$0$Proxy);} else {super.setSuperUser(var1);}}......}
public class ParseConfig {public final SymbolTable symbolTable = new SymbolTable(4096);......}
/** 用户服务类 */@Servicepublic class UserService {/** 超级用户 */public final User superUser = new User(0L, "admin", "超级用户");......}
/** 公司服务类 */@Servicepublic class CompanyService {/** 公司DAO */@Autowiredprivate CompanyDAO companyDAO;/** 用户服务 */@Autowiredprivate UserService userService;/** 删除公司 */public void deleteCompany(Long companyId, Long operatorId) {// 验证超级用户if (!Objects.equals(operatorId, userService.superUser.getId())) {throw new ExampleException("只有超级用户才能删除公司");}// 删除公司信息companyDAO.delete(companyId, operatorId);}}

JavaBean 类必须是一个公共类,并将其访问属性设置为 public,如:public class User{......}
JavaBean 类必须有一个空的构造函数:类中必须有一个不带参数的公用构造器
一个 JavaBean 类不应有公共实例变量,类变量都为 private,如:private Integer id;
属性应该通过一组 getter / setter 方法来访问
重磅 
去年 6 月,《Java 开发手册》发布了华山版,同时还发布了配套的 IDE 插件,在全球 Java 开发者的共同努力下,已成为业界普遍遵循的开发规范,帮助大家高效开发。《Java 开发手册》背后有哪些故事?作者孤尽对华山版有哪些解读?插件该如何使用?哪里可以下载手册的所有版本?

福利来了 
亲爱的同学,你在写 Java 的过程中遇到过哪些坑?有什么经验分享?有没有哪个坑让你终身难忘?欢迎在评论区留言,点赞数前 5 名每人随机送出 1 本技术书籍及小礼物,明天 13:00 截止,祝大家在编程的道路上,永不踩坑 :)


