如何以编程方式读取Java接口?

如何以编程方式读取Java接口?,java,reflection,interface,field,Java,Reflection,Interface,Field,我想实现一个方法,从定义指定(int)值的接口返回字段。我没有接口的源代码 所以,签名可以是这样的: public ArrayList<String> getFieldnames(Object src, int targetValue); public ArrayList getFieldnames(Object src,int targetValue); 我假设它可以在内部找到声明的字段,并根据值测试每个字段,返回列表 ArrayList<String> s = n

我想实现一个方法,从定义指定(int)值的接口返回字段。我没有接口的源代码

所以,签名可以是这样的:

public ArrayList<String> getFieldnames(Object src, int targetValue);
public ArrayList getFieldnames(Object src,int targetValue);
我假设它可以在内部找到声明的字段,并根据值测试每个字段,返回列表

ArrayList<String> s = new ArrayList<String>();

if( src!= null )
{
    Field[] flist = src.getClass().getDeclaredFields();
    for (Field f : flist )
        if( f.getType() == int.class )
            try {
                if( f.getInt(null) == targetValue) {
                    s.add(f.getName());
                    break;
                }
            } catch (IllegalArgumentException e) {
            } catch (IllegalAccessException e) {
            }
}
return s;
arraylists=newarraylist();
如果(src!=null)
{
字段[]flist=src.getClass().getDeclaredFields();
for(字段f:flist)
if(f.getType()==int.class)
试一试{
如果(f.getInt(null)=targetValue){
s、 添加(f.getName());
打破
}
}捕获(IllegalArgumentException e){
}捕获(非法访问例外e){
}
}
返回s;
不幸的是,这个实现是不正确的——当使用接口本身调用时,就好像根本没有字段一样。如果我传递一个实现接口的对象,可能的字段列表将太宽,无法使用

谢谢你的帮助

这个

src.getClass()
返回src类而不是接口。考虑这个

interface I {
}

class A implements I {
}

new A().getClass() -- returns A.class 

虽然我更希望传入一个对象,但我认为将签名更改为字符串值并传入FQIN也可以完成任务

谢谢你的创意(还有谷歌的指导)

解决方案:

public ArrayList<String> getFieldnamesByValue(Class<?>x, int targetValue)
{
    ArrayList<String> s = new ArrayList<String>();

    if( x != null )
    {
        Field[] flist = x.getDeclaredFields();
        for (Field f : flist )
            if( f.getType() == int.class )
                try {
                    if( f.getInt(null) == targetValue) {
                        s.add(f.getName());
                        break;
                    }
                } catch (IllegalArgumentException e) {
                } catch (IllegalAccessException e) {
                }
    }
    return s;
}
public ArrayList getFieldnamesByValue(Classx,int targetValue)
{
ArrayList s=新的ArrayList();
如果(x!=null)
{
字段[]flist=x.getDeclaredFields();
for(字段f:flist)
if(f.getType()==int.class)
试一试{
如果(f.getInt(null)=targetValue){
s、 添加(f.getName());
打破
}
}捕获(IllegalArgumentException e){
}捕获(非法访问例外e){
}
}
返回s;
}
公共数组列表GetFieldName(对象src,int targetValue){
最终类myInterfaceClass=MyInterface.Class;
ArrayList fieldNames=新的ArrayList();
如果(src!=null){
对于(类currentClass=src.getClass();currentClass!=null;currentClass=currentClass.getSuperclass()){
类[]接口=currentClass.getInterfaces();
if(Arrays.asList(interfaces.contains)(myInterfaceClass)){
for(字段:currentClass.getDeclaredFields()){
if(field.getType().equals(int.class)){
试一试{
int value=field.getInt(null);
如果(值==目标值){
add(field.getName());
}
}捕获(非法访问例外){
//什么也不做。总是注释空块。
}
}
}
}
}
}
返回字段名;
}

完全正确!我试图弄清楚如何传入接口,以便能够解析它。我不能调用
getFieldNames(I,aField)
,我不能调用
getFieldNames(new I(){},aField)
(尽管最后一个已编译)-我如何将接口对象传递给方法?可以从对象类->src.getClass().getInterfaces()获取所有接口,或者只需将其作为MyInterface.classe传递,您不需要使用完全限定名。只需从签名中删除
stringinterfacefqname
,删除第一个
try/catch
,并将其替换为
classx=MyInterface.Class这是关键,阿尔文。我将方法的签名改为
getFieldnames(Classsrc,inttargetvalue)
,这样主体就可以直接进入循环。在调用站点,我可以快速地确定
arraylistnames=getFieldNames(sobcontents.class,45)
,瞧!接受这个答案,因为它是最接近的,而不是我自己的,它让我想起了
类型规范!谢谢完整答案见下文。在签名中使用
Class src
,并更改调用站点以传入
MyInterface.Class
。这避免了内部的
getClass()
,工作起来很有魅力!
public ArrayList<String> getFieldnames(Object src, int targetValue) {
  final Class<?> myInterfaceClass = MyInterface.class;
  ArrayList<String> fieldNames = new ArrayList<>();
  if (src != null) {
    for (Class<?> currentClass = src.getClass(); currentClass != null; currentClass = currentClass.getSuperclass()) {
      Class<?> [] interfaces = currentClass.getInterfaces();
      if (Arrays.asList(interfaces).contains(myInterfaceClass)) {
        for (Field field : currentClass.getDeclaredFields()) {
          if (field.getType().equals(int.class)) {
            try {
              int value = field.getInt(null);
              if (value == targetValue) {
                fieldNames.add(field.getName());
              }
            } catch (IllegalAccessException ex) {
              // Do nothing. Always comment empty blocks.
            }
          }
        }
      }
    }
  }
  return fieldNames;
}