gpt4 book ai didi

java - 如何在基类中创建 Java 泛型

转载 作者:行者123 更新时间:2023-11-30 06:59:34 25 4
gpt4 key购买 nike

编辑

根据讨论,我将我的 SystemUnderTestFactory 实现更改为 this (和 tests )

public abstract class BaseUnitTesterWithSut<TSut>
{
protected SystemUnderTestFactory<TSut> SutFactory;

@Before
@SuppressWarnings("unchecked")
public void before()
{
ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
SutFactory = new SystemUnderTestFactory<>((Class<TSut>) type.getActualTypeArguments()[0]);
}
}

public class SystemTester extends BaseUnitTesterWithSut<System>
{
@Test
public void can_subclass_and_test()
{
System sut = SutFactory.sut();
assertThat(sut).isExactlyInstanceOf(System.class);
}
}

原始问题

背景:我是一名 C# 开发人员,刚开始从事 Java 1.8 项目,并试图了解如何在使用 Java 中的泛型工作时完成任务(对我来说,泛型实现和整个类型删除让它们几乎毫无意义).

我想做的是创建一个基类,其中包含一个在基类中实例化并在子类中使用的通用字段(“属性”)。

此外,我正在创建的属性是抽象类的匿名子类,因此我可以使用父类(super class)信息在运行时使用 this "trick" 检查泛型类型(那是一口)

有没有什么方法可以完成下面我想做的事情,而不必在基类中重写方法?在使用 Java 时,我是否只是以错误的方式思考泛型?同样,我已经习惯了 C# 方式来做事,所以如果有一种 Java 方式来做我需要学习/切换到的事情,那么我也会对此感兴趣。

我想完成的事情

public abstract class BaseUnitTesterWithSut<TSut>
{
protected SystemUnderTestFactory<TSut> SutFactory;

@Before
public void before()
{
SutFactory = new SystemUnderTestFactory<TSut>() { };
}
}

public class SystemTester extends BaseUnitTesterWithSut<System>
{
@Test
public void can_subclass_and_test()
{
System sut = SutFactory.sut();
assertThat(sut).isExactlyInstanceOf(System.class);
}
}

我的解决方法

public class SystemTester // extends BaseUnitTesterWithSut<System>
{
protected SystemUnderTestFactory<System> SutFactory;

@Before
public void before()
{
SutFactory = new SystemUnderTestFactory<System>() { }
}

@Test
public void can_subclass_and_test()
{
System sut = SutFactory.sut();
assertThat(sut).isExactlyInstanceOf(System.class);
}
}

SystemUnderTestFactory 的简化版本

它会检查具有最多依赖项的构造函数的类,并为每个依赖项自动创建模拟,当您检索该对象时,它将使用该构造函数和它创建的模拟为您创建一个。

如果您有兴趣可以查看完整的实现here (和 tests )

public abstract class SystemUnderTestFactory<TSut>
{
private final Class<TSut> _type;
private volatile Constructor<?> _ctor;

private ArrayList _dependencies;
private TSut _sut;

public SystemUnderTestFactory()
{
ParameterizedType superclass = (ParameterizedType) getClass().getGenericSuperclass();
_type = (Class<TSut>) superclass.getActualTypeArguments()[0];

_dependencies = new ArrayList();
_ctor = getGreediestCtor();

Class[] parameterTypes = _ctor.getParameterTypes();
for (Class cls : parameterTypes)
{
// Mockito mock
_dependencies.add(mock(cls));
}
}

public TSut sut()
{
return (TSut) _ctor.newInstance(_dependencies.toArray());;
}
}

最佳答案

看起来您可以从 BaseUnitTesterWithSut 而不是 SystemUnderTestFactory 获取类,然后将其传入。

abstract class BaseUnitTesterWithSut<TSut>
{
protected SystemUnderTestFactory<TSut> SutFactory;

@Before
public void before()
{
ParameterizedType thisType = (ParameterizedType) getClass().getGenericSuperclass();
SutFactory = new SystemUnderTestFactory<>((Class<TSut>) thisType.getActualTypeArguments()[0]);
}
}

关于java - 如何在基类中创建 Java 泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31436997/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com