我对Java导入系统有点困惑(我不确定它是关于Java导入还是这个库 - 我使用Apache POI 3.17):
import java.io.FileInputStream;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
public class Main {
public static void main(String[] args) {
try {
Workbook wb = WorkbookFactory.create(new FileInputStream(
"workbook.xls"));
Sheet sheet1 = wb.getSheetAt(0);
for (Row row : sheet1) {
for (Cell cell : row) {
// Alternatively, get the value and format it yourself
switch (cell.getCellTypeEnum()) {
///////////////// Why this is not CellType.STRING
case STRING:
System.out.println(cell.getRichStringCellValue()
.getString());
break;
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
System.out.println(cell.getDateCellValue());
} else {
System.out.println(cell.getNumericCellValue());
}
break;
case BOOLEAN:
System.out.println(cell.getBooleanCellValue());
break;
case FORMULA:
System.out.println(cell.getCellFormula());
break;
case BLANK:
System.out.println();
break;
default:
System.out.println();
}
}
}
} catch (Exception e) {
}
}
}
从导入部分,您可以看到我没有导入:
import org.apache.poi.ss.usermodel.CellType;
为什么此代码在该开关部分中有效?在每种情况下,我只在那里使用枚举类型(如STRING
但不使用CellType.STRING
)。Java 编译器如何知道这些类型来自哪里?我在Eclipse中编辑代码,当我将鼠标悬停在"case STRING"上时,它会显示org.apache.poi.ss.usermodel.CellType.STRING?
JLS第14.11节说:
如果
switch
语句的 Expression 的类型是枚举类型,则与switch
语句关联的每个case
量都必须是该类型的enum
常量。
编译器只需要一个简单的名称,因为它已经知道它需要什么类型。
开关标签:
案例常量表达式:
案例枚举常量名称:
违约:
枚举常量名称:
标识符
Identifier
是一个简单的名字,没有.
.
但这与导入包是不同的概念。 导入不是允许使用类型的机制;这并不是说不导入包不允许使用该包。 毕竟,始终可以使用类型的完全限定名称而不导入它,例如
org.apache.poi.ss.usermodel.CellType cellType = cell.getCellTypeEnum();
导入包对于程序员来说是一种方便,这样我们就不需要在每次需要引用类型时都键入完全限定的类型名称;我们只需要键入简单名称。
JLS 第 7.5 节规定:
导入声明允许使用由单个标识符组成的简单名称 (§6.2) 引用命名类型或
static
成员。如果不使用适当的导入声明,引用另一个包中声明的类型或另一个类型的
static
成员的唯一方法是使用完全限定名 (§6.7)。
导入包不会影响编译器是否知道包或包中的类;为了方便起见,它只允许程序员使用简单的名称。