七种武器:apache commons : commons-lang

前言

有人说apache 就是丐帮,各种开源项目鱼龙混杂,参差不起。

今天试着梳理下commons包,首先是commons-lang。

看了一眼之后,一个字:杂,有如瑞士军刀,用途多而杂。

 

如何organize这种类JDK util代码?

1) the most interesting in design or implementation

2) the most useful 

3) see how other developer uses, wrap, rewrite JDK

正文

lang.builder.*

解决了一个问题,实现以下四个methods时,如果一个class有很多fields,会是一件烦琐和boring的工作。

  • equals
  • toString
  • hashCode
  • compareTo

example code

public boolean equals(Object obj) { if (obj == null) { return false; } if (obj == this) { return true; } if (obj.getClass() != getClass()) { return false; } MyClass rhs = (MyClass) obj; return new EqualsBuilder() .appendSuper(super.equals(obj)) .append(field1, rhs.field1) .append(field2, rhs.field2) .append(field3, rhs.field3) .isEquals(); } 

 

public boolean equals(Object obj) { return EqualsBuilder.reflectionEquals(this, obj); } 

lang.reflect.*

MethodUtils

 

getMatchingAccessibleMethod

Find an accessible method that matches the given name and has compatible parameters. Compatible parameters mean that every method parameter is assignable from the given parameters. In other words, it finds a method with the given name that will take the parameters given.

 

This method can match primitive parameter by passing in wrapper classes. For example, a Boolean will match a primitive boolean parameter.

 

用在invokeMethod中, 使用isAssignableFrom, 实现代码如下:

Method bestMatch = null; Method[] methods = cls.getMethods(); for (int i = 0, size = methods.length; i < size; i++) { if (methods[i].getName().equals(methodName)) { // compare parameters if (ClassUtils.isAssignable(parameterTypes, methods[i] .getParameterTypes(), true)) { // get accessible version of method Method accessibleMethod = getAccessibleMethod(methods[i]); if (accessibleMethod != null) { if (bestMatch == null || MemberUtils.compareParameterTypes( accessibleMethod.getParameterTypes(), bestMatch.getParameterTypes(), parameterTypes) < 0) { bestMatch = accessibleMethod; } } } } } 

 

getAccessibleMethod

 

Return an accessible method (that is, one that can be invoked via reflection) with given name and parameters. If no such method can be found, return null.

用在invokeExactMethod中,主要实现代码如下,getDeclaredMethod 和 getSuperclass 来递归实现

// Search up the superclass chain for (; cls != null; cls = cls.getSuperclass()) { // Check the implemented interfaces of the parent class Class[] interfaces = cls.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { // Is this interface public? if (!Modifier.isPublic(interfaces[i].getModifiers())) { continue; } // Does the method exist on this interface? try { method = interfaces[i].getDeclaredMethod(methodName, parameterTypes); } catch (NoSuchMethodException e) { /* * Swallow, if no method is found after the loop then this * method returns null. */ } if (method != null) { break; } // Recursively check our parent interfaces method = getAccessibleMethodFromInterfaceNest(interfaces[i], methodName, parameterTypes); if (method != null) { break; } } } 


invokeExactMethod

Invoke a static method whose parameter types match exactly the parameter types given.

这个方法和invokeMethod的区别见下面的例子


invokeExactStaticMethod

  Invoke a named static method whose parameter type matches the object type.

静态方法invoke时候,第一个object参数传入null即可 method.invoke(null, args);

 

getMethods 返回所有public的member methods,包括继承的父类和实现的接口中的方法。因此,静态方法也包含在内。


invokeMethod

 

 Invoke a named method whose parameter type matches the object type.

public class Parent { } public class Child extends Parent { } //-------------------------------------------------- // Can pass both Child, Parent // Parent.class.isAssignableFrom(parameter.class) public class Main { public void pass(Parent parameter) { //... } } //-------------------------------------------------- Main main = new Main(); Child child = new Child(); MethodUtils.invokeMethod(main, "pass", child); // OK MethodUtils.invokeExactMethod(child, "pass', child); //exception, java.lang.NoSuchMethodException: No such accessible method: pass() on object: org.leef.Child  

lang.time.*

FastDateFormat
SimpleDateFormat is not thread-safe in any JDK version, nor will it be as Sun have closed the bug/RFE.
why SimpleDateFormat 什么不是线程安全?因为有些field是mutable

有很多解决方法,

每次new 加上synchronize 使用thread-local,和每次new差不多;如果线程重用,则减少了new的次数 使用object-pool,共享多个对象

StopWatch

lang.text.*

StrSubstitutor 

用来替换占位符

Map valuesMap = HashMap(); valuesMap.put("animal", "quick brown fox"); valuesMap.put("target", "lazy dog"); String templateString = "The ${animal} jumped over the ${target}."; StrSubstitutor sub = new StrSubstitutor(valuesMap); String resolvedString = sub.replace(templateString) 

StrTokenizer(对应guava中的splitter)

StrMatcher (对应guava中的CharMatcher)

StrBuilder (对应guava中的Joiner)

lang.*

WordUtils

用来capitalize 

 

StringUtils

有Join 也有split

 

ArrayUtils

nullToEmpty: Defensive programming technique,将null数组转换成empty(size 为0)的数组。

add/remove: 数组添加或者删除元素

lang.math.* lang.exception.*

JVMRandom: ShardSeedRandom, 比Random要快??

RandomUtils

参考

http://www.slideshare.net/tcurdt/apache-commons-dont-reinvent-the-wheel-presentation

 

http://commons.apache.org/lang/userguide.html

 

 

你可能感兴趣的:(java)