1

I'm coding a Excel import logic:

public class ExcelImporter {
    //...ignore constructor and other methods ...
    public <R> Builder<R> sheet(String sheetName, RowConsumer<R> rowConsumer) {
        return new Builder<R>(sheetName, rowConsumer);
    }
    public class Builder<R> {
        //...ignore other method
        public <F> Builder header(String name, CellConsumer<R, F> cellConsumer) {
            sheetReader.header(new DefaultHeader<>(name, cellConsumer));
            return this;
        }
        public <F> Builder header(String name, Class<F> fieldType, CellConsumer<R, String> cellConsumer) {
            return header(name,cellConsumer);
        }
    }
}

And on my test code I got compile error:

@Test
public void processSmallExcelWithConsumer() throws Exception {
    try (InputStream is = getClass().getClassLoader().getResourceAsStream("工作簿1.xls")) {
        ExcelImporter excelImporter = new ExcelImporter(is, "application/vnd.ms-excel")
                .sheet("Sheet1", () -> new RowBean())
                .header("姓名",String.class, (cell, row) -> row.setName(cell)) // no error
                .header("性别",String.class, (cell, row) -> row.setSex(cell)) // "setSex" got error and `row` evaluate to `Object` ? why !?
                .build();

setSex() can not compile,and that row evaluate to Object, I'm so confusion that it works well at first time but fails next time?

This is CellConsumer:

@FunctionalInterface
public interface CellConsumer<R,F> {
    void read(F cell,R row);
}

And RowConsumer:

@FunctionalInterface
public interface RowConsumer<R> {
    R newRow();
}

And error:

[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.797 s
[INFO] Finished at: 2017-07-28T23:56:26+08:00
[INFO] Final Memory: 17M/166M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.2:testCompile (default-testCompile) on project graceful-excel: Compilation failure
[ERROR] /home/terrason/workspace/maven/cnx/graceful-excel/src/test/java/cn/lenyar/excel/ExcelImporterTest.java:[81,66] 找不到符号
[ERROR] 符号:   方法 setSex(java.lang.Object)
[ERROR] 位置: 类型为java.lang.Object的变量 row
[ERROR] -> [Help 1]

Help me please!

3
  • Can you paste exact complete error you are getting and CellConsumer interface. Commented Jul 28, 2017 at 15:49
  • @hagrawal question is update ,sorry for chinese log Commented Jul 28, 2017 at 15:58
  • This needs more context, what is the row class that you're calling setName and setSex on? And what is RowBean? Commented Jul 28, 2017 at 16:21

1 Answer 1

1

The problem is that you aren't specifying the generic type of the returned builder in the header methods:

public <F> Builder header(...)
//this returns Builder which is the same as Builder<?>
//All java can infer from Builder<?> is that the generic type is an Object.
//which makes row in the second call an Object

Try returning Builder<R> in your header methods:

public class ExcelImporter {
  //...ignore constructor and other methods ...
  public <R> Builder<R> sheet(String sheetName, RowConsumer<R> rowConsumer) {
    return new Builder<R>(sheetName, rowConsumer);
  }

  private static class RowBean {
    private String name;
    private String sex;

    public void setName(String name) {
      this.name = name;
    }

    public void setSex(String sex) {
      this.sex = sex;
    }
  }

  public class Builder<R> {
    public Builder(String sheetName, RowConsumer<R> rowConsumer) {

    }

    //...ignore other method
    public <F> Builder<R> header(String name, CellConsumer<R, F> cellConsumer) {
      return this;
    }

    public <F> Builder<R> header(String name, Class<F> fieldType, CellConsumer<R, String> cellConsumer) {
      return header(name, cellConsumer);
    }

    public ExcelImporter build() {
      return null;
    }
  }

  @FunctionalInterface
  public interface CellConsumer<R, F> {
    void read(F cell, R row);
  }

  @FunctionalInterface
  public interface RowConsumer<R> {
    R newRow();
  }

  public static void main(String[] args) {
    ExcelImporter excelImporter = new ExcelImporter()
        .sheet("Sheet1", () -> new RowBean())
        .header("姓名", String.class, (cell, row) -> row.setName(cell)) // no error
        .header("性别", String.class, (cell, row) -> row.setSex(cell)) // no error!
        .build();
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.