Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从带有反射的已解析字符串中获取正确的方法_Java_Parsing_Reflection - Fatal编程技术网

Java 从带有反射的已解析字符串中获取正确的方法

Java 从带有反射的已解析字符串中获取正确的方法,java,parsing,reflection,Java,Parsing,Reflection,我已经创建了一个泛型类,它以一个对象作为输入,并实现了一个方法,该方法给定该对象的一个方法及其参数的字符串表示形式(即“charAt(3)”),从而进行解析并找到正确的方法。 我能够让它为没有参数的方法运行,但原因是我不明白,在其他一些方法上(比如字符串的charAt)不断失败。 这是密码 public class MiniInterpreter<T> { private Class<?> objClass; private T object; public Mini

我已经创建了一个泛型类,它以一个对象作为输入,并实现了一个方法,该方法给定该对象的一个方法及其参数的字符串表示形式(即“charAt(3)”),从而进行解析并找到正确的方法。 我能够让它为没有参数的方法运行,但原因是我不明白,在其他一些方法上(比如字符串的charAt)不断失败。 这是密码

public class MiniInterpreter<T> 
{
private Class<?> objClass;
private T object;

public MiniInterprete(T object)
{
    objClass = object.getClass();
    this.object = object;
}

private static boolean isNumeric(String str)  
{  
  try  
  {  
    @SuppressWarnings("unused")
    int i = Integer.parseInt(str);  
  }  
  catch(NumberFormatException nfe)  
  {  
    return false;  
  }  
  return true;  
}

private static boolean isBoolean(String str)
{
    return (str.equalsIgnoreCase("true") || str.equalsIgnoreCase("false"));
}


private static boolean isDouble(String str)
{
    try
    {
        @SuppressWarnings("unused")
        double d = Double.parseDouble(str);
    }
    catch(NumberFormatException nfe)
    {
        return false;
    }
    return true;
}

public String getName(int index, String str)
{
    if(str.charAt(index) == '(' || str.charAt(index) == ')')
        return "";
    else
        return str.charAt(index) + getName(index + 1, str);
}

public String getParameters(int index, String str)
{
        switch(str.charAt(index))
        {
        case '(': return "" + getName(index + 1, str);
        default: return getParametri(index + 1, str);
        }
}

public Object parse(String method) throws GenericErrorException
{
    String name = getName(0,method);
    String parameters = getParameters(0,method);

    if(!parameters.equals(""))
    {
        return parseParameters(name, parameters.split(","));
    }

    Method m = null;

    try 
    {
        m = objClass.getMethod(name);
    } 
    catch (NoSuchMethodException e) {e.printStackTrace();} 
    catch (SecurityException e) {e.printStackTrace();}

    try 
    {
        return m.invoke(object);
    } 
    catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {throw new GenericErrorException();}

}

private Object parseParameters(String name, String[] parameters) throws GenericErrorException
{
    List<Class<?>> parametersList = new ArrayList<Class<?>>();
    List<Object> parametersArray = new ArrayList<Object>();

    for(String s : parameters)
    {
        Object obj = null;

        if(isNumeric(s))
        {
            obj = Integer.parseInt(s);
        }
        else if(isDouble(s))
        {
            obj = Double.parseDouble(s);
        }
        else if(isBoolean(s))
        {
            obj = Boolean.parseBoolean(s);
        }
        else
            obj = s;

        parametersList.add(obj.getClass());
        parametersArray.add(obj);
    }

    Method m = null;
    Class<?>[] parametersTypeArray = parametersList.toArray(new Class<?>[parametersList.size()]);

    try 
    {
            m = objClass.getMethod(name, parametersTypeArray );
    } 
    catch (NoSuchMethodException | SecurityException e) {e.printStackTrace();}

    try 
    {

        return m.invoke(object, parametersArray.toArray());
    } 
    catch (IllegalAccessException | IllegalArgumentException
            | InvocationTargetException e) {throw new GenericErrorException();}

}

}
公共类小型解释器
{
私有类对象类;
私人T对象;
公共小型解释器(T对象)
{
objClass=object.getClass();
this.object=对象;
}
私有静态布尔值isNumeric(字符串str)
{  
尝试
{  
@抑制警告(“未使用”)
int i=Integer.parseInt(str);
}  
捕获(NumberFormatException nfe)
{  
返回false;
}  
返回true;
}
私有静态布尔值isBoolean(字符串str)
{
返回(str.equalsIgnoreCase(“真”)| | str.equalsIgnoreCase(“假”);
}
专用静态布尔isDouble(字符串str)
{
尝试
{
@抑制警告(“未使用”)
double d=double.parseDouble(str);
}
捕获(NumberFormatException nfe)
{
返回false;
}
返回true;
}
公共字符串getName(int索引,String str)
{
如果(str.charAt(索引)='('| | str.charAt(索引)='))
返回“”;
其他的
返回str.charAt(index)+getName(index+1,str);
}
公共字符串getParameters(int索引、字符串str)
{
开关(str.charAt(索引))
{
大小写“(”:返回“”+getName(索引+1,str);
默认值:返回getParameteri(索引+1,str);
}
}
公共对象解析(字符串方法)引发GenericErrorException
{
String name=getName(0,方法);
字符串参数=getParameters(0,方法);
如果(!parameters.equals(“”)
{
返回parseParameters(名称,parameters.split(“,”);
}
方法m=null;
尝试
{
m=objClass.getMethod(名称);
} 
catch(NoSuchMethodException){e.printStackTrace();}
catch(SecurityException e){e.printStackTrace();}
尝试
{
返回m.invoke(对象);
} 
catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException e){抛出新的GenericeErrorException();}
}
私有对象parseParameters(字符串名称,字符串[]参数)引发GenericeErrorException
{
列表>();
列表参数array=new ArrayList();
用于(字符串s:参数)
{
objectobj=null;
如果(是数字)
{
obj=整数.parseInt(s);
}
否则,如果(是双重的)
{
obj=Double.parseDouble;
}
else if(isBoolean(s))
{
obj=布尔值。解析布尔值;
}
其他的
obj=s;
参数list.add(obj.getClass());
参数array.add(obj);
}
方法m=null;
类[]parametersTypeArray=parametersList.toArray(新类[parametersList.size()]);
尝试
{
m=objClass.getMethod(名称、参数Y);
} 
catch(NoSuchMethodException | SecurityException e){e.printStackTrace();}
尝试
{
返回m.invoke(对象,参数array.toArray());
} 
捕获(IllegalAccessException | IllegalArgumentException
|InvocationTargetException e){抛出新的GenericeErrorException();}
}
}
唯一允许的类型是String、Integer、Boolean和Double,对于方法来说也是如此,我还必须假设没有多个方法具有该名称和参数,我只是想知道我是否忽略了某些内容,或者代码是否因为这个限制而无法正常工作。
当它不起作用时,我会得到noSuchMethod异常,当然,nullPointer异常会导致它不初始化该方法。

正如user1676075所建议的,您的问题是,您正在寻找一个不存在的方法,因为您的签名错误

String#charAt(int)
是您给出的示例。签名是基本类型
int
,它与类
Integer
不同。您使用的

obj = Integer.parseInt(s)
它返回一个
int
类型,因此您可能认为您得到的是一个基元。但是您不能将基元存储在对象中,Java知道这一点。由于
obj
是一个
对象
,Java自动将基元
int
装箱为
整数
。然后您需要一个名为
charAt
的方法nd签名
Integer
,JRE表示从未听说过

如果您只满足于使用采用
int
的方法,而忽略任何采用
整数的方法(这将涵盖大多数标准库),则可以指定类型:

obj = Integer.parseInt(s);
parametersList.add(Integer.TYPE);  // the type of primitive ints

但是,如果您想正确地执行此操作,则需要使代码更加复杂。与其调用
Class#getMethod()
,我还不如调用
Class#getDeclaredMethods())
,找到具有您要查找的名称的子集,然后查看该方法的参数列表是否与您的参数类型兼容。

添加.fix类该程序在所有公共方法上都能平稳运行,错误在私有方法parseParameters中,甚至不需要为其创建第二个方法这两种截然不同的情况(解析带有参数的字符串或empty()),为getMethod提供一个空列表,无论如何都会得到正确的结果,感谢您的支持

for(String s : parameters)
    {

        if(isNumeric(s))
        {
            parametersList.add(int.class);
            parametersArray.add(Integer.parseInt(s));
        }
        else if(isDouble(s))
        {
            parametersList.add(double.class);
            parametersArray.add(Double.parseDouble(s));
        }
        else if(isBoolean(s))
        {
            parametersList.add(boolean.class);
            parametersArray.add(Boolean.parseBoolean(s));
        }
        else
        {
            parametersList.add(s.getClass());
            parametersArray.add(s);
        }

您能发布一个实际的字符串和实际的方法签名吗?请记住int和Integer是不同的方法签名。m=objClass.getMethod(name,parametersTypeArray);这是生成错误的行,它在parseParameters中。当输入字符串在方法中没有参数(如长度)时,调用一个私有方法。让我看看是否得到它,自动装箱/取消装箱Let charAt(整数