2017-07-18 49 views
0

我有一個文本文件,作爲參數傳遞給我的程序。該文件包含類名和參數,我應該實例:獲取作爲文件輸入接收的參數類型

Home: 
SmartMeter:30,false 

我想創建實例,使用反射,但我無法弄清楚如何獲得的實際類型的,我從文件中獲取的參數。我得到這個之後,我想將它們與這個類的所有構造函數的參數類型進行比較,並選擇正確的。這是迄今爲止我所編寫的代碼:

Scanner scan = new Scanner(new File(args[0])); 
    String[] classNameAndParameters; 
    String[] parameters; 

    while (scan.hasNextLine()) { 
     classNameAndParameters = scan.nextLine().split(":"); 
     Class<?> c = Class.forName(classNameAndParameters[0]); 

     // i check for the length too because it throws arrayoutofbounds exception 
     if (classNameAndParameters.length > 1 && classNameAndParameters[1] != null) { 
      parameters = classNameAndParameters[1].split(","); 


      // get all constructors for the created class 
      Constructor<?>[] constructors = c.getDeclaredConstructors(); 

      for(int i = 0; i < constructors.length; i++) { 
       Constructor<?> ct = constructors[i]; 
       Class<?> pvec[] = ct.getParameterTypes(); 

       for (int j = 0; j < pvec.length; j++) { 
        System.out.println("param #" + j + " " + pvec[j]); 
       } 
      } 
      //i should match the parameter types of the file with the parameters of the available constructors 


      //Object object = consa.newInstance(); 
     } else { 
      // default case when the constructor takes no arguments 
      Constructor<?> consa = c.getConstructor(); 
      Object object = consa.newInstance(); 
     } 
    } 

    scan.close(); 

回答

0

你需要指定在文本文件中的參數類型,否則它是不可能的Java解決一些在運行參數的不確定性。

例如,如果你有類圖書:

public class Book { 
    public Book() { 
    } 

    public Book(Integer id, String name) { 
    } 

    public Book(String idx, String name) { 
    } 
} 

你提供書:30,飢餓遊戲

又會有怎樣的代碼知道哪個構造函數來接,因爲30是一個合法的整數,還合法的字符串?

假設沒有你的構造函數是模糊的,這裏是如何做到這一點:

String args[] = {"this is id", "this is name"}; 

Arrays.asList(Book.class.getConstructors()).stream() 
    .filter(c -> c.getParameterCount() == args.length).forEach(c -> { 
     if (IntStream.range(0, c.getParameterCount()).allMatch(i -> { 
     return Arrays.asList(c.getParameterTypes()[i].getDeclaredMethods()).stream() 
      .filter(m -> m.getName().equals("valueOf")).anyMatch(m -> { 
       try { 
       m.invoke(null, args[i]); 
       return true; 
       } catch (Exception e) { 
       return false; 
       } 
      }); 
     })) 
     System.out.println("Matching Constructor: " + c); 
    }); 
+0

當我更換args數組,你用構造函數的參數個數進行比較,我得到一個錯誤 - 局部變量在封閉範圍內定義的參數必須是最終的或有效的最終。 – prego

+0

是的,根據Java Spec,lambda要求:「一個lambda表達式只能訪問局部變量和封閉塊的最終或有效最終參數」。對不起,但我不太清楚你的意思,因爲parameterCount()是一個整數,參數是一個字符串數組 –

+0

我的意思是parameters.length – prego