简体   繁体   中英

How to use two interfaces as argument using generics in Java?

I'm trying to wrapp two interfaces in one to not have to rewrite each method using each interface. I searched a lot but I don't know how can I do this:

class ApplyFilter
{

  public static File[] filter (File directory, FileFilterORFilenameFilter filterWrapper)
  {
    return directory.listenFiles(filterWrapper);
  }

}

I tried it creating a class that implements both interfaces but then I need to cast the variable. I also tried using java generics using a class like this:

public class CustomFilter<T>
{

  /*  Where we store our filter  */
  private T filter = null;

  /*  The method to return it  */
  public T getFilter ()
  {
    return filter;
  }

  /*  The constructor to define the filter  */
  public CustomFilter (T filt)
  {
    if ( !(filt instanceof FileFilter) || !(filt instanceof FilenameFilter) ) throw new IllegalArgumentException("The argument must be an instance of FilenameFilter or a FileFilter.");
    this.filter = filt;
  }

}

Then I used it like this and it worked:

class test
{

  public static void main (String[] args)
  {
    CustomFilter<FileFilter> onlyShowFolders = new CustomFolder<FileFilter>(new FileFilter ()
    {
      @Override
      public boolean accept (File file)
      {
        return file.isDirectory();
      }
    });

    File root = new File("/");
    for (File folder : root.listFiles(onlyShowFolders.getFilter()))
    {
      System.out.print(folder.toPath());
    }
  }

}

But when I use it in the ApplyFilter class it doesn't work.

class ApplyFilter
{

  /*  DOESN'T WORK :(  */
  public static File[] filter (File directory, CustomFilter filterWrapper)
  {
    return directory.listenFiles(filterWrapper.getFilter());
  }

}

Thanks in advance.

You can do like what the java library itself does with File.listFiles ie two functions with same name and different argument type.

class ApplyFilter {

    public static File[] filter(File directory, FileFilter filter) {
        return directory.listFiles(filter);
    }

    public static File[] filter(File directory, FilenameFilter filter) {
        return directory.listFiles(filter);
    }

}

Example holder class, see comments

public class FilterHolder {
    private FileFilter fileFilter;
    private FilenameFilter filenameFilter;

    public FilterHolder(FileFilter fileFilter) {
        this.fileFilter = fileFilter;
    }

    public FilterHolder(FilenameFilter filenameFilter) {
        this.filenameFilter = filenameFilter;
    }

    public FileFilter getFileFilter() {
        return fileFilter;
    }

    public FilenameFilter getFilenameFilter() {
        return filenameFilter;
    }
}

It does not work because you omit the most important part for the compiler so that it compile:

  public static File[] filter (File directory, CustomFilter filterWrapper)
  {
    return directory.listenFiles(filterWrapper.getFilter());
  }

The actual type representation is:

  public static File[] filter (File directory, CustomFilter<Object> filterWrapper)
  {
    return directory.listenFiles(filterWrapper.getFilter());
  }

And then, it looks for a method listenFiles taking an Object as single parameter.

Beside, FilenameFilter and FileFilter does not have a common ancestor, and you can't restrict the type of T, like this:

public class CustomFilter<T extends FileFilter>
{

  /*  Where we store our filter  */
  private T filter = null;

  /*  The method to return it  */
  public T getFilter () {
    return filter;
  }

  /*  The constructor to define the filter  */
  public CustomFilter (T filt) {
    this.filter = Objects.requireNonNull(filt, "filt");
  }
}

If you are sure you always use the FileFilter , you should probably don't use your CustomFilter and stick with FileFilter unless you know you will add more functionalities. But in that case, have CustomFilter implements FileFilter .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM