关于反射里的内部类和外部类

    最近写适配,遇到了一点小问题,

1.通过反射得到某个实例,可是这个实例是内部类,想要得到并通过invoke方法执行外部类的方法,需要得到外部类的实例,通过网上查阅,每一个内部类都有一个this$0的变量是指向外部类的引用,通过getdeclearedField得到这个引用,然后setaccessible(true)得到访问权限实例化外部类就得到了,此时这个内部类的实例对应的外部类的实例了。

      可是我这里的内部类是static的,上面的this$0是有限制的,静态内部类和静态方法里面的内部类是没有this$0这个引用的,因为静态内部类,是面向类的而不是对象,能够独自的应用本身,而脱离外部类,和外部类没有这个引用关系。

2.     还有一个方法是要invoke的方法在内部类,得到的实例是外部类,想得到对应的内部类的实例,并没有这层关系。所以这个方法不可行

在这里记录下通过外部类得到内部类的方法:

clazz.getDeclaredClasses();

通过内部类得到外部类的方法:

Clazz.getDeclaringClass();

得到类的构造函数

clazz.getConstructors()

得到类的所有构造函数

clazz.getDeclaredConstructor();

注意:构造函数通过getmethod是得不到的!只能通过getdeclaredconstructor/getconstructors得到

最后解决的办法,在前辈的帮助下,发现setheader方法,最终是走的内部类的request里面的add方法这样就不需要关联内部类和外部类了。下面是asynchttpclient一个类的代码:

package com.ning.http.client;

import com.ning.http.client.cookie.Cookie;

import com.ning.http.client.multipart.Part;

import com.ning.http.client.uri.Uri;

import com.ning.http.util.AsyncHttpProviderUtils;

import com.ning.http.util.MiscUtils;

import com.ning.http.util.UriEncoder;

import java.io.File;

import java.io.InputStream;

import java.net.InetAddress;

import java.util.ArrayList;

import java.util.Collection;

import java.util.Collections;

import java.util.List;

import java.util.Map;

import java.util.Map.Entry;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public abstract class RequestBuilderBase<T extends RequestBuilderBase<T>>

{

  private static final Logger logger = LoggerFactory.getLogger(RequestBuilderBase.class);

  private static final Uri DEFAULT_REQUEST_URL = Uri.create("http://localhost");

  private final Class<T> derived;

  protected final RequestImpl request;

  protected UriEncoder uriEncoder;

  protected List<Param> rbQueryParams;

  protected SignatureCalculator signatureCalculator;

  

  private static final class RequestImpl

    implements Request

  {

    private String method;

    private Uri uri;

    private InetAddress address;

    private InetAddress localAddress;

    private FluentCaseInsensitiveStringsMap headers = new FluentCaseInsensitiveStringsMap();

    private ArrayList<Cookie> cookies;

    private byte[] byteData;

    private List<byte[]> compositeByteData;

    private String stringData;

    private InputStream streamData;

    private BodyGenerator bodyGenerator;

    private List<Param> formParams;

    private List<Part> parts;

    private String virtualHost;

    private long length = -1L;

    public ProxyServer proxyServer;

    private Realm realm;

    private File file;

    private Boolean followRedirects;

    private int requestTimeout;

    private long rangeOffset;

    public String charset;

    private ConnectionPoolPartitioning connectionPoolPartitioning = ConnectionPoolPartitioning.PerHostConnectionPoolPartitioning.INSTANCE;

    private NameResolver nameResolver = NameResolver.JdkNameResolver.INSTANCE;

    private List<Param> queryParams;

    

    public RequestImpl() {}

    

    public RequestImpl(Request prototype)

    {

      if (prototype != null)

      {

        this.method = prototype.getMethod();

        this.uri = prototype.getUri();

        this.address = prototype.getInetAddress();

        this.localAddress = prototype.getLocalAddress();

        this.headers = new FluentCaseInsensitiveStringsMap(prototype.getHeaders());

        this.cookies = new ArrayList(prototype.getCookies());

        this.byteData = prototype.getByteData();

        this.compositeByteData = prototype.getCompositeByteData();

        this.stringData = prototype.getStringData();

        this.streamData = prototype.getStreamData();

        this.bodyGenerator = prototype.getBodyGenerator();

        this.formParams = (prototype.getFormParams() == null ? null : new ArrayList(prototype.getFormParams()));

        this.parts = (prototype.getParts() == null ? null : new ArrayList(prototype.getParts()));

        this.virtualHost = prototype.getVirtualHost();

        this.length = prototype.getContentLength();

        this.proxyServer = prototype.getProxyServer();

        this.realm = prototype.getRealm();

        this.file = prototype.getFile();

        this.followRedirects = prototype.getFollowRedirect();

        this.requestTimeout = prototype.getRequestTimeout();

        this.rangeOffset = prototype.getRangeOffset();

        this.charset = prototype.getBodyEncoding();

        this.connectionPoolPartitioning = prototype.getConnectionPoolPartitioning();

        this.nameResolver = prototype.getNameResolver();

      }

    }

    

    public String getMethod()

    {

      return this.method;

    }

    

    public InetAddress getInetAddress()

    {

      return this.address;

    }

    

    public InetAddress getLocalAddress()

    {

      return this.localAddress;

    }

    

    public Uri getUri()

    {

      return this.uri;

    }

    

    public String getUrl()

    {

      return this.uri.toUrl();

    }

    

    public FluentCaseInsensitiveStringsMap getHeaders()

    {

      return this.headers;

    }

    

    public Collection<Cookie> getCookies()

    {

      return this.cookies != null ? Collections.unmodifiableCollection(this.cookies) : Collections.emptyList();

    }

    

    public byte[] getByteData()

    {

      return this.byteData;

    }

    

    public List<byte[]> getCompositeByteData()

    {

      return this.compositeByteData;

    }

    

    public String getStringData()

    {

      return this.stringData;

    }

    

    public InputStream getStreamData()

    {

      return this.streamData;

    }

    

    public BodyGenerator getBodyGenerator()

    {

      return this.bodyGenerator;

    }

    

    public long getContentLength()

    {

      return this.length;

    }

    

    public List<Param> getFormParams()

    {

      return this.formParams != null ? this.formParams : Collections.emptyList();

    }

    

    public List<Part> getParts()

    {

      return this.parts != null ? this.parts : Collections.emptyList();

    }

    

    public String getVirtualHost()

    {

      return this.virtualHost;

    }

    

    public ProxyServer getProxyServer()

    {

      return this.proxyServer;

    }

    

    public Realm getRealm()

    {

      return this.realm;

    }

    

    public File getFile()

    {

      return this.file;

    }

    

    public Boolean getFollowRedirect()

    {

      return this.followRedirects;

    }

    

    public int getRequestTimeout()

    {

      return this.requestTimeout;

    }

    

    public long getRangeOffset()

    {

      return this.rangeOffset;

    }

    

    public String getBodyEncoding()

    {

      return this.charset;

    }

    

    public ConnectionPoolPartitioning getConnectionPoolPartitioning()

    {

      return this.connectionPoolPartitioning;

    }

    

    public NameResolver getNameResolver()

    {

      return this.nameResolver;

    }

    

    public List<Param> getQueryParams()

    {

      if (this.queryParams == null) {

        if (MiscUtils.isNonEmpty(this.uri.getQuery()))

        {

          this.queryParams = new ArrayList(1);

          for (String queryStringParam : this.uri.getQuery().split("&"))

          {

            int pos = queryStringParam.indexOf('=');

            if (pos <= 0) {

              this.queryParams.add(new Param(queryStringParam, null));

            } else {

              this.queryParams.add(new Param(queryStringParam.substring(0, pos), queryStringParam.substring(pos + 1)));

            }

          }

        }

        else

        {

          this.queryParams = Collections.emptyList();

        }

      }

      return this.queryParams;

    }

    

    public String toString()

    {

      StringBuilder sb = new StringBuilder(getUrl());

      

      sb.append("\t");

      sb.append(this.method);

      sb.append("\theaders:");

      if (MiscUtils.isNonEmpty(this.headers)) {

        for (String name : this.headers.keySet())

        {

          sb.append("\t");

          sb.append(name);

          sb.append(":");

          sb.append(this.headers.getJoinedValue(name, ", "));

        }

      }

      if (MiscUtils.isNonEmpty(this.formParams))

      {

        sb.append("\tformParams:");

        for (Param param : this.formParams)

        {

          sb.append("\t");

          sb.append(param.getName());

          sb.append(":");

          sb.append(param.getValue());

        }

      }

      return sb.toString();

    }

  }

  

  protected RequestBuilderBase(Class<T> derived, String method, boolean disableUrlEncoding)

  {

    this(derived, method, UriEncoder.uriEncoder(disableUrlEncoding));

  }

  

  protected RequestBuilderBase(Class<T> derived, String method, UriEncoder uriEncoder)

  {

    this.derived = derived;

    this.request = new RequestImpl();

    this.request.method = method;

    this.uriEncoder = uriEncoder;

  }

  

  protected RequestBuilderBase(Class<T> derived, Request prototype)

  {

    this(derived, prototype, UriEncoder.FIXING);

  }

  

  protected RequestBuilderBase(Class<T> derived, Request prototype, UriEncoder uriEncoder)

  {

    this.derived = derived;

    this.request = new RequestImpl(prototype);

    this.uriEncoder = uriEncoder;

  }

  

  public T setUrl(String url)

  {

    return setUri(Uri.create(url));

  }

  

  public T setUri(Uri uri)

  {

    this.request.uri = uri;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setInetAddress(InetAddress address)

  {

    this.request.address = address;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setLocalInetAddress(InetAddress address)

  {

    this.request.localAddress = address;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setVirtualHost(String virtualHost)

  {

    this.request.virtualHost = virtualHost;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setHeader(String name, String value)

  {

    this.request.headers.replaceWith(name, new String[] { value });

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T addHeader(String name, String value)

  {

    if (value == null)

    {

      logger.warn("Value was null, set to \"\"");

      value = "";

    }

    this.request.headers.add(name, value);

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setHeaders(FluentCaseInsensitiveStringsMap headers)

  {

    this.request.headers = (headers == null ? new FluentCaseInsensitiveStringsMap() : new FluentCaseInsensitiveStringsMap(headers));

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setHeaders(Map<String, Collection<String>> headers)

  {

    this.request.headers = (headers == null ? new FluentCaseInsensitiveStringsMap() : new FluentCaseInsensitiveStringsMap(headers));

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setContentLength(int length)

  {

    this.request.length = length;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  private void lazyInitCookies()

  {

    if (this.request.cookies == null) {

      this.request.cookies = new ArrayList(3);

    }

  }

  

  public T setCookies(Collection<Cookie> cookies)

  {

    this.request.cookies = new ArrayList(cookies);

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T addCookie(Cookie cookie)

  {

    lazyInitCookies();

    this.request.cookies.add(cookie);

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T addOrReplaceCookie(Cookie cookie)

  {

    String cookieKey = cookie.getName();

    boolean replace = false;

    int index = 0;

    lazyInitCookies();

    for (Cookie c : this.request.cookies)

    {

      if (c.getName().equals(cookieKey))

      {

        replace = true;

        break;

      }

      index++;

    }

    if (replace) {

      this.request.cookies.set(index, cookie);

    } else {

      this.request.cookies.add(cookie);

    }

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public void resetCookies()

  {

    if (this.request.cookies != null) {

      this.request.cookies.clear();

    }

  }

  

  public void resetQuery()

  {

    this.rbQueryParams = null;

    this.request.uri = this.request.uri.withNewQuery(null);

  }

  

  public void resetFormParams()

  {

    this.request.formParams = null;

  }

  

  public void resetNonMultipartData()

  {

    this.request.byteData = null;

    this.request.compositeByteData = null;

    this.request.stringData = null;

    this.request.streamData = null;

    this.request.bodyGenerator = null;

    this.request.length = -1L;

  }

  

  public void resetMultipartData()

  {

    this.request.parts = null;

  }

  

  public T setBody(File file)

  {

    this.request.file = file;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setBody(byte[] data)

  {

    resetFormParams();

    resetNonMultipartData();

    resetMultipartData();

    this.request.byteData = data;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setBody(List<byte[]> data)

  {

    resetFormParams();

    resetNonMultipartData();

    resetMultipartData();

    this.request.compositeByteData = data;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setBody(String data)

  {

    resetFormParams();

    resetNonMultipartData();

    resetMultipartData();

    this.request.stringData = data;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setBody(InputStream stream)

  {

    resetFormParams();

    resetNonMultipartData();

    resetMultipartData();

    this.request.streamData = stream;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setBody(BodyGenerator bodyGenerator)

  {

    this.request.bodyGenerator = bodyGenerator;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T addQueryParam(String name, String value)

  {

    if (this.rbQueryParams == null) {

      this.rbQueryParams = new ArrayList(1);

    }

    this.rbQueryParams.add(new Param(name, value));

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T addQueryParams(List<Param> params)

  {

    if (this.rbQueryParams == null) {

      this.rbQueryParams = params;

    } else {

      this.rbQueryParams.addAll(params);

    }

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  private List<Param> map2ParamList(Map<String, List<String>> map)

  {

    if (map == null) {

      return null;

    }

    List<Param> params = new ArrayList(map.size());

    for (Map.Entry<String, List<String>> entries : map.entrySet())

    {

      name = (String)entries.getKey();

      for (String value : (List)entries.getValue()) {

        params.add(new Param(name, value));

      }

    }

    String name;

    return params;

  }

  

  public T setQueryParams(Map<String, List<String>> map)

  {

    return setQueryParams(map2ParamList(map));

  }

  

  public T setQueryParams(List<Param> params)

  {

    if (MiscUtils.isNonEmpty(this.request.uri.getQuery())) {

      this.request.uri = this.request.uri.withNewQuery(null);

    }

    this.rbQueryParams = params;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T addFormParam(String name, String value)

  {

    resetNonMultipartData();

    resetMultipartData();

    if (this.request.formParams == null) {

      this.request.formParams = new ArrayList(1);

    }

    this.request.formParams.add(new Param(name, value));

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setFormParams(Map<String, List<String>> map)

  {

    return setFormParams(map2ParamList(map));

  }

  

  public T setFormParams(List<Param> params)

  {

    resetNonMultipartData();

    resetMultipartData();

    this.request.formParams = params;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T addBodyPart(Part part)

  {

    resetFormParams();

    resetNonMultipartData();

    if (this.request.parts == null) {

      this.request.parts = new ArrayList();

    }

    this.request.parts.add(part);

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setProxyServer(ProxyServer proxyServer)

  {

    this.request.proxyServer = proxyServer;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setRealm(Realm realm)

  {

    this.request.realm = realm;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setFollowRedirects(boolean followRedirects)

  {

    this.request.followRedirects = Boolean.valueOf(followRedirects);

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setRequestTimeout(int requestTimeout)

  {

    this.request.requestTimeout = requestTimeout;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setRangeOffset(long rangeOffset)

  {

    this.request.rangeOffset = rangeOffset;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setMethod(String method)

  {

    this.request.method = method;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setBodyEncoding(String charset)

  {

    this.request.charset = charset;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setConnectionPoolKeyStrategy(ConnectionPoolPartitioning connectionPoolKeyStrategy)

  {

    this.request.connectionPoolPartitioning = connectionPoolKeyStrategy;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setNameResolver(NameResolver nameResolver)

  {

    this.request.nameResolver = nameResolver;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  public T setSignatureCalculator(SignatureCalculator signatureCalculator)

  {

    this.signatureCalculator = signatureCalculator;

    return (RequestBuilderBase)this.derived.cast(this);

  }

  

  private void executeSignatureCalculator()

  {

    if (this.signatureCalculator != null)

    {

      RequestBuilder rb = (RequestBuilder)new RequestBuilder(this.request).setSignatureCalculator(null);

      rb.rbQueryParams = this.rbQueryParams;

      Request unsignedRequest = rb.build();

      this.signatureCalculator.calculateAndAddSignature(unsignedRequest, this);

    }

  }

  

  private void computeRequestCharset()

  {

    if (this.request.charset == null) {

      try

      {

        String contentType = this.request.headers.getFirstValue("Content-Type");

        if (contentType != null)

        {

          String charset = AsyncHttpProviderUtils.parseCharset(contentType);

          if (charset != null) {

            this.request.charset = charset;

          }

        }

      }

      catch (Throwable localThrowable) {}

    }

  }

  

  private void computeRequestLength()

  {

    if ((this.request.length < 0L) && (this.request.streamData == null))

    {

      String contentLength = this.request.headers.getFirstValue("Content-Length");

      if (contentLength != null) {

        try

        {

          this.request.length = Long.parseLong(contentLength);

        }

        catch (NumberFormatException localNumberFormatException) {}

      }

    }

  }

  

  private void validateSupportedScheme(Uri uri)

  {

    String scheme = uri.getScheme();

    if ((scheme == null) || ((!scheme.equalsIgnoreCase("http")) && (!scheme.equalsIgnoreCase("https")) && (!scheme.equalsIgnoreCase("ws")) && 

      (!scheme.equalsIgnoreCase("wss")))) {

      throw new IllegalArgumentException("The URI scheme, of the URI " + uri + ", must be equal (ignoring case) to 'http', 'https', 'ws', or 'wss'");

    }

  }

  

  private void computeFinalUri()

  {

    if (this.request.uri == null)

    {

      logger.debug("setUrl hasn't been invoked. Using {}", DEFAULT_REQUEST_URL);

      this.request.uri = DEFAULT_REQUEST_URL;

    }

    else

    {

      validateSupportedScheme(this.request.uri);

    }

    this.request.uri = this.uriEncoder.encode(this.request.uri, this.rbQueryParams);

  }

  

  public Request build()

  {

    executeSignatureCalculator();

    computeFinalUri();

    computeRequestCharset();

    computeRequestLength();

    return this.request;

  }

}

猜你喜欢

转载自blog.csdn.net/dataiyangu/article/details/81317784