它不是很面向对象:statics可能被某些人认为是“邪恶的”,一个原因是它们与面向对象的范式背道而驰。特别是,它违反了数据封装在对象(可以扩展,信息隐藏等)中的原则。静态,在你描述使用它们的方式中,本质上是将它们用作全局变量,以避免处理诸如范围之类的问题。但是,全局变量是过程式或命令式编程范式的定义特征之一,而不是“好的”面向对象代码的特征。这并不是说过程范式不好,但我得到的印象是,你的主管希望你编写“好的面向对象代码”,而你真的想写“好的过程代码”。
当你开始使用静态时,Java中有许多gothiyas并不总是很明显。例如,如果在同一 VM 中运行两个程序副本,它们是否会粉碎静态变量的值并弄乱彼此的状态?或者,在扩展类时会发生什么,是否可以重写静态成员?VM 的内存不足是否因为静态数据数量过多,并且无法为其他需要的实例对象回收内存?
对象生存期:此外,静态数据的生存期与程序的整个运行时相匹配。这意味着,即使使用完类,也无法对所有这些静态变量中的内存进行垃圾回收。例如,如果您使变量成为非静态变量,并且在 main() 函数中创建了类的单个实例,然后要求类执行特定函数 10,000 次,一旦完成这 10,000 次调用,并且您删除了对单个实例的引用,则所有静态变量都可以被垃圾回收并重用。
防止某些重复使用:此外,静态方法不能用于实现接口,因此静态方法可以阻止某些面向对象的功能可用。
其他选项:如果效率是你主要关心的问题,那么可能还有其他更好的方法来解决速度问题,而不是只考虑调用通常比创建更快的优势。考虑在任何地方是否需要瞬态或易失性修饰符。为了保持内联能力,可以将方法标记为 final 而不是 static。方法参数和其他变量可以标记为 final,以允许某些编译器根据关于什么可以更改这些变量的假设进行优化。一个实例对象可以多次重用,而不是每次都创建一个新实例。通常,可能应为应用启用编译器优化开关。也许,应该设置设计,以便10,000次运行可以多线程并利用多处理器内核。如果portablity不是一个问题,也许原生方法会让你比静态方法更好的速度。
如果由于某种原因你不希望一个对象的多个副本,单例设计模式,比静态对象有优势,比如线程安全(假设你的单例编码得很好),允许延迟初始化,保证对象在使用时已经正确初始化,子类,测试和重构代码的优势,更不用说,如果你在某些时候改变主意只想要一个对象的一个实例,那就容易多了。删除代码以防止重复实例,而不是重构所有静态变量代码以使用实例变量。我以前不得不这样做,这并不好玩,你最终不得不编辑更多的类,这增加了你引入新错误的风险......第一次就把事情“正确”设置好要好得多,即使它似乎有其缺点。对我来说,如果你决定需要一些东西的多个副本,所需的返工可能是尽可能少地使用静态的最令人信服的理由之一。因此,我也不同意你关于静态技术减少相互依赖关系的说法,我认为,如果你有大量可以直接访问的静态数据,而不是一个“知道如何做某事”的对象,你最终会得到更多耦合的代码。