retrofit 源码优秀代码功能点学习

2021-03-08  本文已影响0人  Android小悟空

@Nullable和@Nonnull的使用

在编写方法时,入参、返回值,记得要用@Nullable和@Nonnull修饰,来达到提醒调用方的目的(kotlin应该不用)

泛型的大量使用

一个好的架构,一定是可以兼容各种数据类型,各种场景的,所以通过泛型可以很好的解决这些问题,所以泛型的使用是架构设计的核心

public interface TypeQualifierValidator<A extends Annotation> {
    public @Nonnull
    When forConstantValue(@Nonnull A annotation, Object value);
}
public final class Response<T> {
  /** Create a synthetic successful response with {@code body} as the deserialized body. */
  public static <T> Response<T> success(@Nullable T body) {
    return success(
        body,
        new okhttp3.Response.Builder() //
            .code(200)
            .message("OK")
            .protocol(Protocol.HTTP_1_1)
            .request(new Request.Builder().url("http://localhost/").build())
            .build());
  }
}  
public <T> T create(final Class<T> service) {
    validateServiceInterface(service);
}

private void validateServiceInterface(Class<?> service) {
    if (!service.isInterface()) {
      throw new IllegalArgumentException("API declarations must be interfaces.");
    }
    
    Deque<Class<?>> check = new ArrayDeque<>(1);
}

final class

retrofit 源码中有大量的类都是使用final来修饰的
final修饰class有以下特点 :

String类就是一个final类:

public final class String implements Serializable, Comparable<String>, CharSequence {
    ...
}

final 修饰方法时:

public class B extends A {
  public void getName() {

  }
}

class A {
  public final void getName() {

  }
}

当A类的getName是被final修饰时,如果B extends A ,那么不能重写getName方法,会直接报错:
getName()' cannot override 'getName()' in 'retrofit2.A'; overridden method is final

final 修饰变量时:

static final class

public static final class Builder {}

build模式和工厂模式(工厂、抽象工厂)的使用

<? extends Annotation>和<?, ?>的使用

@Override
public Class<? extends Annotation> annotationType() {
    return SkipCallbackExecutor.class;
}

abstract class(抽象类)的使用

abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

    Type returnType = method.getGenericReturnType();
    if (Utils.hasUnresolvableType(returnType)) {
      throw methodError(
          method,
          "Method return type must not include a type variable or wildcard: %s",
          returnType);
    }
    if (returnType == void.class) {
      throw methodError(method, "Service methods cannot return void.");
    }

    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

  abstract @Nullable T invoke(Object[] args);
}

使用String字符串拼接时,要用StringBuilder

StringBuilder builder =
    new StringBuilder("Could not locate call adapter for ").append(returnType).append(".\n");
if (skipPast != null) {
  builder.append("  Skipped:");
  for (int i = 0; i < start; i++) {
    builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
  }
  builder.append('\n');
}
builder.append("  Tried:");
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
  builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());

StringBuilder效率高,线程不安全
StringBuffer效率低,线程安全

Objects.requireNonNull(type, "type == null");的使用

Objects.requireNonNull(type, "type == null");
Objects.requireNonNull(parameterAnnotations, "parameterAnnotations == null");
Objects.requireNonNull(methodAnnotations, "methodAnnotations == null");

底层(sdk组件)字段校验可以使用这样的方式,来避免调用方传一些错误字段,但是上层业务不能这样写,要处理异常而不是抛出

for循环中创建count对象

for (int i = start, count = converterFactories.size(); i < count; i++) {
  Converter.Factory factory = converterFactories.get(i);
  Converter<?, RequestBody> converter =
      factory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, this);
  if (converter != null) {
    //noinspection unchecked
    return (Converter<T, RequestBody>) converter;
  }
}

for循环中,使用count = converterFactories.size()的方法,直接创建了count对象

反射reflect中Type的意义和使用

/**
 * Extract the upper bound of the generic parameter at {@code index} from {@code type}. For
 * example, index 1 of {@code Map<String, ? extends Runnable>} returns {@code Runnable}.
 */
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
  return Utils.getParameterUpperBound(index, type);
}

/**
 * Extract the raw class type from {@code type}. For example, the type representing {@code
 * List<? extends Runnable>} returns {@code List.class}.
 */
protected static Class<?> getRawType(Type type) {
  return Utils.getRawType(type);
}

List作为返回值,而不是ArrayList等

public List<Converter.Factory> converterFactories() {
return converterFactories;
}

动态代理的使用

public <T> T create(final Class<T> service) {
    validateServiceInterface(service);
    return (T)
        Proxy.newProxyInstance(
            service.getClassLoader(),
            new Class<?>[] {service},
            new InvocationHandler() {
              private final Platform platform = Platform.get();
              private final Object[] emptyArgs = new Object[0];

              @Override
              public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
                  throws Throwable {
                // If the method is a method from Object then defer to normal invocation.
                if (method.getDeclaringClass() == Object.class) {
                  return method.invoke(this, args);
                }
                args = args != null ? args : emptyArgs;
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args);
              }
            });
  }

用线程池Executor而不是直接使用new Thread()

final @Nullable Executor callbackExecutor;

package-info.java的使用

@retrofit2.internal.EverythingIsNonNull
package retrofit2;

package-info.java是一个特殊的类,可以对整个包做操作。
retrofit中使用package-info.java为retrofit2包中的每一个类都添加了注释@retrofit2.internal.EverythingIsNonNull

kotlin中泛型、内联函数、扩展函数的用法:


inline fun <reified T> Retrofit.create(): T = create(T::class.java)
上一篇 下一篇

猜你喜欢

热点阅读