问题描述
在Delphi中,有所谓的类引用:
type
TSomeClass = class(TAncestorClass)
.
.
end;
// They are declared with some weird syntax: (I know Java has no type declarations)
type
TSomeClassReference = class Of TSomeClass;
声明这样的声明,可以将其用作参数
// you can pass TSomeClassReference or any descendant class this function
function ClassFactory (pClassToCreate : TSomeClassReference) : TSomeClass;
// invoke with
var
A : TSomeClass;
B : TSomeClassDerivedFromTSomeClass;
A := ClassFactory (TSomeClass);
B := ClassFactory (TSomeClassDerivedFromTSomeClass);
B := ClassFactory (TAnotherClass); // wrong!
或实例变量
TAnotherClass = class(TAnyClassNotDerivedFromTSomeClass)
.
.
// same: can hold reference to TSomeClass or any descendant
FDriverClass : TSomeClassReference;
end;
var
A : TAnotherClass;
A.FDriverClass := TSomeClass;
A.FDriverClass := TSomeClassDerivedFromTSomeClass;
A.FDriverClass := TAnotherClass; // wrong!
我在Delphi中大量使用此类类引用来创建类工厂。 Java是否有执行此操作的语法? 我的意思是
public TSomeClass ClassFactory (pClassToCreate TSomeClassReference)
{...}
要么
public class TAnotherClass extends TAnyClass {
TSomeClassReference FDriverClass;
}
1楼
在Java 7中,可以通过在类名中添加.class
来获得类引用。
例如
Class<Integer> iClass = Integer.class
但是,如果要使用工厂,则在Java 8中建议使用Supplier
因为这要灵活得多。
Supplier<Integer> iSupplier = () -> new Integer(0);
Integer i = iSupplier.get();
2楼
在Java中, 等效于Delphi中的TClass
。
Java 类具有getClass()
方法,该方法返回特定对象实例的类,类似于Delphi的TObject
类ClassType
方法
public final Class<?> getClass() // Java
function ClassType: TClass; // Delphi
例如String.class
类型是Class<String>
为了获得等效的Delphi元类TSomeClassReference
声明为
TSomeClassReference = class Of TSomeClass;
在Java中,应在Class<T>
上使用
Class<? extends SomeClass>
这将给您像Delphi一样的编译时类型检查。
以下示例演示Java中的简单对象工厂
public class BaseClass
{
public int b = 0;
public BaseClass()
{
b = 10;
}
}
public class ClassA extends BaseClass
{
public ClassA()
{
b = 20;
}
}
public class ClassAA extends ClassA
{
public ClassAA()
{
b = 22;
}
}
public class ClassB extends BaseClass
{
public ClassB()
{
b = 30;
}
}
public class BaseFactory
{
public static BaseClass create(Class<? extends BaseClass> clazz)
{
try
{
return clazz.getConstructor().newInstance();
}
catch (NoSuchMethodException e)
{
e.printStackTrace();
}
catch (InvocationTargetException e)
{
e.printStackTrace();
}
catch (InstantiationException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
return null;
}
}
然后您可以使用工厂来创建类似
Class<? extends BaseClass> c = ClassA.class;
BaseClass o = BaseFactory.create(c);
要么
BaseClass o = BaseFactory.create(BaseClass.class);
BaseClass o = BaseFactory.create(ClassA.class);
BaseClass o = BaseFactory.create(ClassAA.class);
BaseClass o = BaseFactory.create(ClassB.class);
Class<? extends BaseClass> c = String.class; // this will not compile
BaseClass o = BaseFactory.create(String.class); // this will not compile
Delphi中的等效对象工厂-类型名称已更改为与Delphi编码样式匹配。
BaseClass
- TBaseObject
ClassA
- TObjectA
Class<? extends BaseClass>
Class<? extends BaseClass>
TBaseClass
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Classes;
type
TBaseObject = class(TObject)
public
b: integer;
constructor Create; virtual;
end;
TBaseClass = class of TBaseObject;
TObjectA = class(TBaseObject)
public
constructor Create; override;
end;
constructor TBaseObject.Create;
begin
inherited;
b := 10;
end;
constructor TObjectA.Create;
begin
inherited;
b := 20;
end;
function BaseFactory(clazz: TBaseClass): TBaseObject;
begin
Result := clazz.Create;
end;
var
o: TBaseObject;
c: TBaseClass;
begin
o := BaseFactory(TBaseObject);
writeln(o.b); // 10
o.Free;
o := BaseFactory(TObjectA);
writeln(o.b); // 20
o.Free;
c := TObjectA;
o := BaseFactory(c);
writeln(o.b); // 20
o.Free;
readln;
end.