我是Java的新手,在一种情况下,我的构造函数中有一个excel对象,而我必须在函数/方法中调用该对象。我的代码看起来像
public class Hotel {
Hotel() throws BiffException, IOException {
FileInputStream configurationExcel=new FileInputStream("C://Users//Rashmi//Desktop//TravalPS_RegregrestionTest1.xls");
Workbook book = Workbook.getWorkbook(configurationExcel);
Sheet firstsheet= book.getSheet(0);
}
public void test(){
Cell excelcell= firstsheet.getCell(2, 2);//this line is throwing error
}
我想在测试功能中使用首页对象,我该如何实现呢?
您想要分配firstSheet
给该类的成员变量,以便可以通过其他方法访问它:
public class Hotel {
/** Variables defined here are accessible in the entire class */
private Sheet mFirstSheet;
Hotel() throws BiffException, IOException {
/* Variables defined here are only accessible within these curly braces */
FileInputStream configurationExcel = new FileInputStream("...");
Workbook book = Workbook.getWorkbook(configurationExcel);
mFirstSheet = book.getSheet(0);
}
public void test() {
Cell excelcell = mFirstSheet.getCell(2, 2);
}
}
注意定义和初始化之间的区别。mFirstSheet
被定义在类(类的花括号内)的身体,但它初始化在构造函数中。定义变量的位置决定了可从何处访问该变量。
关于可访问性的另一点,您的类被定义为public,但是您的构造函数(Hotel() ...
)上没有修饰符。在Java中,默认情况下将其设置为私有包(这意味着仅同一包中的其他类,或者如果没有包,则位于同一目录中,请参见此构造函数)。这意味着,尽管其他软件包中的类可以看到该类,但它们无法创建该类的新版本。这可能是您的意图,并且有某些用途,但是我猜不是这样,因此您可能也想将构造函数公开:public Hotel() ...
有了关于范围界定的新发现知识,可能会很想这样做,以便在#justincase中到处都可以访问所有内容。不要这样 原因如下:
它污染名称空间
假设您有几种方法可以从工作表中获取一个单元格,但是您已将excelcell
变量定义为类中的私有字段(与放在同一位置mFirstSheet
)。现在,所有与以前完全不同的单元格进行交互的方法都将它们存储在同一变量中。现在,这让您头疼不已,请确保excelcell
在使用该方法之前正确初始化该方法,否则它将获得其他方法的单元格,因此此变量的作用域应保持在所使用的每种方法的范围内。
它留下了长期存在的参考资料
Java是垃圾收集的,这意味着,当内存不足时,有一个名为垃圾收集器的系统会查找不再有任何引用附加到其上的对象,并释放与它们关联的内存。离开方法的范围后,定义的变量将不再可用,因此,如果不存在对它们的其他引用,则垃圾收集器可以摆脱它们)。但是,如果您将所有变量都分配为类的私有字段,则只要类的实例存在,它们将至少存在(因为该实例现在包含对该对象的引用)。
configurationExcel
变量将是对象的一个很好的例子。就目前而言,一旦离开构造函数,很可能会收集垃圾。这样做很好,因为它包含一个文件指针,而您实际上不想让它保持打开状态的时间比必要的时间长(有可能book
保留对它的引用,但是由于它的目的,我猜测它可能并没有这样做) 。但是,如果它是一个私有字段,则它将一直存在,直到该类的实例一直未使用时,它的内存就被浪费了。
它破坏了封装
除了将私有字段公开之外,情况并非总是如此。您会注意到,当我定义时mFirstSheet
,我将其设置为private Sheet
。这意味着只能由此类本身(及其内部类和静态上下文)访问。如果将其定义为public Sheet mFirstSheet
,那么任何东西都可以访问它,一开始似乎是个好主意,因为它省去了编写一个getter来让程序的其他部分访问它的麻烦,但是它这不是一个好主意。这意味着您无法控制类的内部状态会发生什么,可以用任何方法代替它:
public class ChaosMonkey() {
public static void wreakHavoc(Hotel hotel) {
hotel.mFirstSheet = null;
/** Havoc wreaked */
}
}
而且您不知道何时,为何或如何。
(此时您可能在想:如果我确实希望其他类能够进行修改,该怎么办mFirstSheet
。如果这是您的类设计的一部分,则其他类应该能够不受任何限制地更改其内部状态,那么这是一个错误的设计,表明存在争议的字段不属于该类的事实。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句