我读过一些讨论静态类变量加载和静态方法加载的文章,但很少有关于从静态方法返回的示例化对象及其足迹的文章。
从静态方法返回示例实际上是创建单例的方式,但是单例应该创建一次,然后由某个getInstance方法访问。
如果我自愿地想要打破单例模式,那么如果我编写类似下面的代码会发生什么?(注意RandomSumBuilder build()方法的静态访问修饰符)
public class Service {
public void doSomething() {
for (int i = 0; i < 1000; i++) {
System.out.println("Random sum : " + RandomSumBuilder.add().build());
}
}
}
public class RandomSumBuilder {
private List<Integer> aList = new ArrayList<>();
public RandomSumBuilder() { }
public static RandomSumBuilder add() {
RandomSumBuilder randomSumBuilder = new RandomSumBuilder();
randomSumBuilder.aList.add(new Random().nextInt(11));
return randomSumBuilder;
}
public int build() {
return aList.stream()
.reduce(Integer::sum)
.orElse(0);
}
}
对我来说,很明显,RandomSumBuilder不能被认为是单例的,但是我不能让我的头围绕这些问题,我只能做出假设。
1.不同的RandomSumBuilder示例是静态的吗?
- 我会说是的,就像单身狗一样 *
1.是否可以选择这些对象进行垃圾回收?
- (根据我对问题1的回答,我会说不)*
1.它是否在类加载器上增加了不必要的工作?
- (如果必须加载那么多RandomSumBuilder来示例化这些静态对象,我会说是的,因为我不认为保持它们全局性有什么意义。我用visualvm进行的快速本地测试无法帮助我做出决定)*
1.构建器模式(带有嵌套类)会带来什么呢?
- (我想说创建的静态对象和类加载工作少得多,但在我的第四个连续假设,我甚至不确定)*
我希望我在这个问题上没有太迷失,如果我错了请纠正我。
1条答案
按热度按时间50pmv0ei1#
请注意,您的示例是不可编译的,因此无法确定
1.不同的
RandomSumBuilder
示例是静态的吗?这个问题毫无意义。
说真的,没有静态示例这回事。
例如:
myTest
* 变量 * 是静态变量,但它所指向的 * 示例 * 与Test
的任何其他示例没有区别。它不是一个“静态示例”。* 没有这样的东西。*
第二个问题是,您的示例根本没有创建任何
RandomSumBuilder
示例。1.是否可以选择1这些对象进行垃圾回收?
是的。假设它们没有被 * 分配 * 给某个使其可达的东西。
1.它是否在类加载器上增加了不必要的工作?
不会。除非你创建多个类加载器,否则类只加载一次。类加载器不会参与创建示例。
1.构建器模式(带有嵌套类)会带来什么呢?
一个对象是如何被创建的,它的可达性是没有区别的,创建它的方法是静态的,内部的还是嵌套的也没有区别。
另一方面,您的程式码会执行下列动作:
因为
instanceB
没有声明,所以不能编译,但是如果instanceB
被声明,并且它是static
,那么这就足以使你(可能)创建的Integer
可达。但这与
build
方法是静态的无关...1 -英语错误:你把“候选人”等同于“选举”。垃圾收集是不民主的。而且即使在真实的世界中,候选人也有比这更广泛的含义。查字典...