当前位置: 代码迷 >> java >> 类似于Java Delphi的类引用
  详细解决方案

类似于Java Delphi的类引用

热度:31   发布时间:2023-07-31 11:26:03.0

在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;
}

在Java 7中,可以通过在类名中添加.class来获得类引用。

例如

Class<Integer> iClass = Integer.class

但是,如果要使用工厂,则在Java 8中建议使用Supplier因为这要灵活得多。

Supplier<Integer> iSupplier = () -> new Integer(0);
Integer i = iSupplier.get();

在Java中, 等效于Delphi中的TClass Java 类具有getClass()方法,该方法返回特定对象实例的类,类似于Delphi的TObjectClassType方法

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.
  相关解决方案