Java易错小结
String 相关运算
- String使用是注意是否初始化,未初始化的全部为null。不要轻易使用
string.isEmpty()
等,首先确保string非空。
推荐使用StringUtils.isNotBlank()
:
public static boolean isNotEmpty(String str)
判断某字符串是否非空,等于!isEmpty(String str),这里不能排除空格字符
下面是示例:
StringUtils.isNotEmpty(null) = false
StringUtils.isNotEmpty("") = false
StringUtils.isNotEmpty(" ") = true
StringUtils.isNotEmpty(" ") = true
StringUtils.isNotEmpty("bob") = true
StringUtils.isNotEmpty(" bob ") = true
public static boolean isNotBlank(String str)
判断某字符串是否不为空且长度不为0且不由空白符(whitespace)构成,等于!isBlank(String str)
下面是示例:
StringUtils.isNotBlank(null) = false
StringUtils.isNotBlank("") = false
StringUtils.isNotBlank(" ") = false
StringUtils.isNotBlank(" ") = false
StringUtils.isNotBlank("/t /n /f /r") = false
StringUtils.isNotBlank("/b") = true
StringUtils.isNotBlank("bob") = true
- Create a new String instance with specified length and filled with specific character.
String filled = StringUtils.repeat("*", 10);
-
concat()方法首先获取拼接字符串的长度,判断这个字符串长度是否为0(判断这个用来拼接的字符串是不是空串),如果是就返回原来的字符串(等于没有拼接)!!!!!;否则就获取源字符串的长度,创建一个新的char[]字符数组,这个字符数组的长度是拼接字符串的长度与源字符串的长度之和,通过Arrays类的copyOf方法复制源数组,然后通过getChars方法将拼接字符串拼接到源字符串中,然后将新串返回。
-
public String substring(int beginIndex, int endIndex)
注意是第二个参数结束下标下一个,不是字符串长度!
String.split()方法,返回是一个数组
我在应用中用到一些,给大家总结一下,仅供大家参考:
1、如果用“.”作为分隔的话,必须是如下写法,String.split("\."),这样才能正确的分隔开,不能用String.split(".");
2、如果用“|”作为分隔的话,必须是如下写法,String.split("\|"),这样才能正确的分隔开,不能用String.split("|");
“.”和“|”都是转义字符,必须得加"\";
3、如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如,“acount=? and uu =? or n=?”,把三个都分隔出来,可以用String.split("and|or");
使用String.split方法分隔字符串时,分隔符如果用到一些特殊字符,可能会得不到我们预期的结果。
我们看jdk doc中说明
public String[] split(String regex)
Splits this string around matches of the given regular expression.
异常处理
try...catch(多个异常) 多个异常采取同样的解决措施
package per.jizuiku.base;
/**
* @author 给最苦
* @date 2019/06/29
* @blog www.cnblogs.com/jizuiku
*/
class Demo {
/**
* @param args
*/
public static void main(String[] args) {
try {
int a = 1 / 0;// 除以0
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
// 多个异常见用 | 隔开
// 多个异常必须是平级关系
System.out.println("发生了ArithmeticException 或者 ArrayIndexOutOfBoundsException 异常");
}
try {
int[] a = {1, 2};
System.out.println(a[3]); // 越界
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
// 出现多个异常,采取同样的处理措施
// 多个异常见用 | 隔开
// 多个异常必须是平级关系
System.out.println("发生了ArithmeticException 或者 ArrayIndexOutOfBoundsException 异常");
}
}
}
类型转换相关
1.只有基础类型才能强制类型转换:
(short)0; //OK
(Short)0; //False
BigDecimal
中的divide
主要就是用来做除法的运算。其中有这么一个方法.
public BigDecimal divide(BigDecimal divisor,int scale, int roundingMode)
第一个参数是除数,第二个参数代表保留几位小数,第三个代表的是使用的模式。其中我们标题上就是其中的两种
BigDecimal.ROUND_DOWN
:直接省略多余的小数,比如1.28如果保留1位小数,得到的就是1.2
BigDecimal.ROUND_UP
:直接进位,比如1.21如果保留1位小数,得到的就是1.3
BigDecimal.ROUND_HALF_UP
:四舍五入,2.35保留1位,变成2.4
BigDecimal.ROUND_HALF_DOWN
:四舍五入,2.35保留1位,变成2.3
后边两种的区别就是如果保留的位数的后一位如果正好是5的时候,一个舍弃掉,一个进位。
BeanUtils.copyProperties(A,B)
请慎用,要检查所有拷贝字段的数据类型是否一致!
但是封装类型和非封装可以转换的,int转long等是可以的。
容器相关
1.当我们迭代一个ArrayList或者HashMap时,如果尝试对集合做一些修改操作(例如删除元素),可能会抛出java.util.ConcurrentModificationException的异常。
当使用Iterator遍历list时候不能直接使用list.add或者list.remove!
Example:
public static void main(String args[]){
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
for(Iterator<String> it = list.iterator();it.hasNext();){
String value = it.next();
if(value.equals("4")) {
it.remove();
list.add("6");
}
System.out.println("List Value:"+value);
}
}
解决方案
The ConcurrentModificationException is thrown when calling String value = it.next();. But the actual culprit is list.add("6");. You mustn't modify a Collection while iterating over it directly. You are using it.remove(); which is fine, but not list.add("6");.
You can however fix this, but you'll need a ListIterator
for(ListIterator<String> it = list.listIterator(); it.hasNext();){
String value = it.next();
if(value.equals("4")) {
it.remove();
it.add("6");
}
System.out.println("List Value:"+value);
}
This should do the trick!
And if I may offer a Java 8 alternative:
List<String> newList = list.stream()
.map(s -> s.equals("4") ? "6" : s)
.collect(Collectors.toList());
Here we create a Stream from your List. We map all values to themselves, only "4" gets mapped to "6" and then we collect it back into a List. But caution, newList is immutable! This is also less efficient, but a lot more elegant (imho).
listiterator.add()方法会把新元素添加到listiterator当前所指位置的左边,listiterator.next()不鸟这个新来的不鸟他(不管正向还是反向都不管 previous()可以联系它)
Spring Boot 相关
1 @Component, @Service, @Controller, @Repository是spring注解,注解后可以被spring框架所扫描并注入到spring容器来进行管理,这些都会被创建新对象!Static类不能使用
@Component是通用注解,其他三个注解是这个注解的拓展,并且具有了特定的功能
@Repository注解在持久层中,具有将数据库操作抛出的原生异常翻译转化为spring的持久层异常的功能。
@Controller层是spring-mvc的注解,具有将请求进行转发,重定向的功能。
@Service层是业务逻辑层注解,这个注解只是标注该类处于业务逻辑层。
用这些注解对应用进行分层之后,就能将请求处理,义务逻辑处理,数据库操作处理分离出来,为代码解耦,也方便了以后项目的维护和开发。
-
BeanUtils.copyProperties(Object source, Object target)
-
Refer error message above “If you want to run this job again, change the parameters.” The formula is JobInstance = JobParameters + Job. If you do not have any parameters for JobParameters, just pass a current time as parameter to create a new JobInstance. For example,
CustomJobLauncher.java
//...
@Component
public class CustomJobLauncher {
@Autowired
JobLauncher jobLauncher;
@Autowired
Job job;
public void run() {
try {
JobParameters jobParameters =
new JobParametersBuilder()
.addLong("time",System.currentTimeMillis()).toJobParameters();
JobExecution execution = jobLauncher.run(job, jobParameters);
System.out.println("Exit Status : " + execution.getStatus());
} catch (Exception e) {
e.printStackTrace();
}
}
}
数据库相关
1. JDBC queryForObject
Returns:
the result object of the required type, or null in case of SQL NULL
Throws:
- IncorrectResultSizeDataAccessException - if the query does not return exactly one row, or does not return exactly one column in that row
- DataAccessException - if the query fails
In queryForObject()
if the results not found, JdbcTemplate does not returns null, instead it throws EmptyResultDataAccessException
. But it’s good to return null, otherwise it may breaks the application flow. Following is the example to handle EmptyResultDataAccessException
and return null.
public User findById(Long id) {
String sql = "SELECT * FROM USER where ID = ?";
try {
return jdbcTemplate.queryForObject(sql, new Object[] { id }, new UserMapper());
} catch (EmptyResultDataAccessException e) {
// Log error
return null;
}
}
2. IS NULL and IS NOT NULL Operators
We cannot use the comparison operators, =,<,>,<>, to test for NULL values. Instead, we have to use IS NULL and IS NOT NULL predicates.
我们不能使用比较运算符=,<,>,<>来测试NULL值。 相反,我们必须使用IS NULL和IS NOT NULL 谓词 。
-
IS NULL: Return rows that contain NULL values
-
IS NULL :返回包含NULL值的行
JDBC queryForList
注意如果数据库本身内容为NULL也会返回一条信息:NULL
!
关于SQL函数
SQL 语句是 select max(proc_Date)
,即使本来没有记录(NULL
), query
也会返回一条所有记录都是NULL
的结果
Maven
很快地找到所需的Dependency,并配置到你的pom.xml里面最快捷方法:
- GOOGLE搜索:maven 你需的jar包名称 repository: 比如我要做EJB,我要找jboss-j2ee.jar的Dependency
就在GOOGLE里输入
maven jboss-j2ee repository
在结果的第一条,进去你就可以在页面里找到下面这段
<dependency>
<groupId>jboss</groupId>
<artifactId>jboss-j2ee</artifactId>
<version>4.0.2</version>
</dependency>
你把上面这段代码贴到你的Maven项目的pom适当的位置去
IDEA
【任务标记是以注释的方式定义】
一、作用:
1、代码量非常大的项目,在某一行中需要在后续阶段实现一个功能,如果不标注下次再找的时候就非常困难了,可以大大的提高开发效率!
2、在团队合作中,还可以告诉别人某处敏感代码的状态。
二、以下为常见的两种注释标记:
1、// TODO
: 表示在此处将要实现的功能,提醒你在后续阶段将会在此处添加代码
2、// FIXME
: 表示此处的代码逻辑有出入,或者根本不能运行,提醒你在后续阶段将会修改此处代码
Java反射
java如何利用反射将父类转为子类(向下转型)?
有检查的写法是:
pulic static <T extends U,U> Optional<T> safeCast(Class<T> class, U object)
{
if(class.isInstance(obj))
return Optional.of((T)obj);
return
Optional.empty();
}
Spring JDBC
QueryTimeoutException
public class QueryTimeoutException extends TransientDataAccessException
Exception to be thrown on a query timeout. This could have different causes depending on the database API in use but most likely thrown after the database interrupts or stops the processing of a query before it has completed.
This exception can be thrown by user code trapping the native database exception or by exception translation.