title: How to give hint in Java that two type parameters are actually the same type?
body: <p>I'm working with AOSP's <a href="https://developer.android.com/reference/android/hardware/camera2/CaptureRequest" rel="nofollow noreferrer"><code>CaptureRequest</code></a> and its associated <a href="https://developer.android.com/reference/android/hardware/camera2/CaptureRequest.Builder" rel="nofollow noreferrer"><code>CaptureRequest.Builder</code></a> classes, and have (albeit very <em>unusual</em> case of) a need to copy settings key-values from an existing instance of <code>CaptureRequest</code> to a new instance of <code>CaptureRequest.Builder</code><sup>1</sup>.</p>
  <p>The basic code here that I want to run is the following:</p>
  <pre class="lang-java prettyprint-override"><code>        for(CaptureRequest.Key&lt;?&gt; key : request.getKeys()) {
              builder.set(key, request.get(key));
          }
  </code></pre>
  <p>... where <code>CaptureRequest.Builder.set()</code> function is defined as <code>&lt;T&gt; void set(Key&lt;T&gt; key, T value)</code>, and <code>CaptureRequest.get()</code> is defined as <code>&lt;T&gt; T get(Key&lt;T&gt; key)</code>.
  But that makes compiler barf with the following error:</p>
  <pre class="lang-java prettyprint-override"><code>Source.java:2: error: method set in class Builder cannot be applied to given types;
                  builder.set(key, request.get(key));
                         ^
    required: Key&lt;T&gt;,T
    found: Key&lt;CAP#1&gt;,CAP#2
    reason: inferred type does not conform to lower bound(s)
      inferred: CAP#1
      lower bound(s): Object
    where T is a type-variable:
      T extends Object declared in method &lt;T&gt;set(Key&lt;T&gt;,T)
    where CAP#1,CAP#2 are fresh type-variables:
      CAP#1 extends Object from capture of ?
      CAP#2 extends Object from capture of ?
  </code></pre>
  <p>If I'm interpreting the error correctly, it's trying to say that it cannot relate <code>&lt;T&gt;</code>s of two functions as being the same one <code>T</code>.  So to give it a hint that it's the same <code>T</code>, I created some helper functions that should make it obvious that it's the same <code>T</code>, and so I have this:</p>
  <pre class="lang-java prettyprint-override"><code>private static &lt;T&gt; T getKeyValue(CaptureRequest request, CaptureRequest.Key&lt;T&gt; key) {
      return (T)request.&lt;T&gt;get(key);
  }
  
  private static &lt;T&gt; void setKeyValue(CaptureRequest.Builder builder, CaptureRequest.Key&lt;T&gt; key) {
      builder.&lt;T&gt;set(key, (T)MyClass.&lt;T&gt;getKeyValue(key));
  }
  
  .....
  
          for(CaptureRequest.Key&lt;?&gt; key : request.getKeys()) {
              setKeyValue(builder, key);
          }
  </code></pre>
  <p>This fails to pacify the Java compiler and it spits out very similar error to the previous one:</p>
  <pre class="lang-java prettyprint-override"><code>  Source.java:6: error: method getKeyValue in class MyClass cannot be applied to given types;
          builder.&lt;T&gt;set(key, (T)MyClass.&lt;T&gt;getKeyValue(key));
                                        ^
    required: CaptureRequest,Key&lt;T#1&gt;
    found: Key&lt;T#2&gt;
    reason: actual and formal argument lists differ in length
    where T#1,T#2 are type-variables:
      T#1 extends Object declared in method &lt;T#1&gt;getKeyValue(CaptureRequest,Key&lt;T#1&gt;)
      T#2 extends Object declared in method &lt;T#2&gt;setKeyValue(Builder,Key&lt;T#2&gt;)
  </code></pre>
  <p>How can I perform this [what should be simple] copy of key-values in a sane way?</p>
  <hr />
  <p><sup>1</sup> Yes, I know that's weird and a bit backwards from typical use of API, hence &quot;unusual&quot;.  Context is that already built request (beyond library's scope) is percolating through a library that needs to shadow request with its own, mostly mimicking the original, but slightly amended, and said library doesn't have access to original builder to build the shadow sibling request. Yes, it's weird and is beyond the scope of this question. This question is really about Java's template methods and apparent compilation error.</p>