2016-09-26 19 views
1

我一直試圖在Java中使用反射,這是我的代碼:的Java:NoSuchMethodException與反射的方法時,明顯存在

String charsetName = "UTF-16LE"; 
java.nio.charset.CharsetDecoder cd = Charset.forName(charsetName).newDecoder(); 

Class c = cd.getClass(); 

Class[] paramTypes = new Class[] {ByteBuffer.class, CharBuffer.class }; 

try { 
    Method method = c.getDeclaredMethod("decodeLoop", paramTypes); 
    method.setAccessible(true); 
    assertTrue(true); 
} catch (NoSuchMethodException | SecurityException e) { 
    e.printStackTrace(); 
    assertTrue(false); 
} 

方法明顯存在。 Java源:

package java.nio.charset; 

public abstract class CharsetDecoder { 
... 
    protected abstract CoderResult decodeLoop(ByteBuffer in, 
              CharBuffer out); 
... 
} 

輸出:

java.lang.NoSuchMethodException: sun.nio.cs.UTF_16LE$Decoder.decodeLoop(java.nio.ByteBuffer, java.nio.CharBuffer) 
at java.lang.Class.getDeclaredMethod(Class.java:2130) 
at com.krasutski.AppTest.testDeclaredMethod(AppTest.java:227) 
... 

如果我使用的參數的charsetName作爲

  • 「UTF-16LE」 - 異常NoSuchMethodException
  • 「UTF-16BE」 - 異常NoSuchMethodException
  • 「UTF-8」 - 很好
  • 「CP1252」 - 很好

我應該如何解決這個問題?

+0

你爲什麼這樣做呢? decodeLoop(in,out)的反射調用結果與使用官方API調用cd.onMalformedInput(CodingErrorAction.REPORT).decode(in,out,false)完全相同...... – Holger

回答

4

你呼籲實際cdgetDeclaredMethod,而它的宣佈CharsetDecoder。鑑於它是一個抽象類,這不能是cd的實際類型。

只要改變這一點:

Class c = cd.getClass(); 

Class c = CharsetDecoder.class; 

異常消失在這一點上。如果它適用於UTF-8和cp1252,則表明用於該的類也是聲明decodeLoop,而對於UTF-16LEUTF-16BE,它們可能被繼承。