Jos*_*z_2 6 java generics java-8
我正在阅读如何实例化一个通用的,并在阅读并应用这个答案之后 ; 我想知道期待Supplier<T>与预期新实例之间的区别T.
例:
abstract class AbstractService<T extends AbstractEntity> {
protected Supplier<T> makeNewThing(); // supplier is expected
public T myMethod(){
T object = makeNewThing().get(); // local object by calling supplier
object.doStuff();
return object;
}
}
class CarService extends AbstractService<Car> {
public Supplier<Car> makeNewThing(){
return Car::new;
}
}
Run Code Online (Sandbox Code Playgroud)
与
abstract class AbstractService<T extends SomeAbstractEntity> {
protected T makeNewThing(); // object is expected, newness is assumed
public T myMethod(){
T object = makeNewThing(); // local object by calling constructor
object.doStuff();
return object;
}
}
class CarService extends AbstractService<Car> {
public Car makeNewThing(){
return new Car();
}
}
Run Code Online (Sandbox Code Playgroud)
我唯一能想到的是期望供应商确保创建一个新对象,但是当期望一个对象时,我们只能假设实现类正在调用构造函数而不是重用现有实例.
我想知道其他客观差异和可能的用例,如果有的话.提前致谢.
使用Supplier推迟创建实例.
这意味着您可以避免创建不必要的实例.
例如,假设您将输出传递makeNewThing()给某个方法.
public void makeNewThingSometimes (T newInstance)
{
if (someCondition) {
this.instance = newInstance;
}
}
public void makeNewThingSometimes (Supplier<T> supplier)
{
if (someCondition) {
this.instance = supplier.get();
}
}
Run Code Online (Sandbox Code Playgroud)
调用第一个变体需要创建一个T实例,即使您不打算使用它.
调用第二个变量仅在必要时创建T的实例.
使用a Consumer可以保存存储(如果创建实例需要大量内存)和时间(如果构造函数的执行是扩展的).
我唯一能想到的是,期待一个供应商可以确保创建一个新对象,
不必要。
您可以Supplier通过以下方式实现:
return SomeEntityImplementation::new;
Run Code Online (Sandbox Code Playgroud)
但你可以用其他方式实现它:
if (myCachedObject != null){
return (()-> myCachedObject);
}
return SomeEntityImplementation::new;
Run Code Online (Sandbox Code Playgroud)
两种方式都可以用于返回缓存的对象或创建新的对象。
优点之一是创建对象Supplier的情况:该对象实际上仅在调用方法时才创建。SupplierSupplier.get()
请注意,在您的示例中, usingSupplier不会带来任何优势,因为在两种情况下(有或没有Supplier),对象创建已经以惰性方式执行:在调用工厂方法时。
要利用它,您应该有一个提供Supplier<T> as 参数的方法,如 Eran 和 Dasblinkenlight 示例中所示。
另一个Supplier优点是它能够实现可能返回多个事物的工厂。
使用Supplier可以让代码更短、更易读,而且不依赖 Java Reflection。
假设你想从一个值创建对象Enum,你可以这样写:
public enum MyBaseClassFactory {
ENUM_A (A::new),
ENUM_B (B::new),
ENUM_C (C::new),
ENUM_D (D::new);
private Supplier<BaseClass> supplier;
MyBaseClassFactory (Supplier<BaseClass> supplier){
this.supplier = supplier;
}
public BaseClass createObject(){
return supplier.get();
}
}
Run Code Online (Sandbox Code Playgroud)
你可以这样使用它:
BaseClass base = MyBaseClassFactory.ENUM_A.createObject();
Run Code Online (Sandbox Code Playgroud)
如果没有Supplier,您将不得不使用反射(可能在运行时失败)或编写冗长且难以维护的代码。
例如,使用反射:
public enum MyEnumFactoryClass {
ENUM_A(A.class), ENUM_B(B.class), ENUM_C(C.class), ENUM_D(D.class);
private Class<BaseClass> clazz;
MyEnumFactoryClass(Class<BaseClass> clazz) {
this.clazz = clazz;
}
public BaseClass createObject() {
return clazz.newInstance();
}
}
Run Code Online (Sandbox Code Playgroud)
例如,没有反射但有更详细的代码:
public enum MyEnumFactoryClass {
ENUM_A {
@Override
public BaseClass createObject() {
return new A();
}
},
ENUM_B {
@Override
public BaseClass createObject() {
return new B();
}
},
ENUM_C {
@Override
public BaseClass createObject() {
return new C();
}
},
ENUM_D {
@Override
public BaseClass createObject() {
return new D();
}
};
public abstract BaseClass createObject();
}
Run Code Online (Sandbox Code Playgroud)
您当然可以通过将Supplier它与Map<String, Supplier<BaseClass>>.
| 归档时间: |
|
| 查看次数: |
1409 次 |
| 最近记录: |