如何在APEX中内省变量的类?

问题描述 投票:4回答:7

我想在运行时知道变量/属性的类。例如:

Integer i = 5;

//pseudo-code
if (i.className == 'Integer') {
    System.debug('This is an integer.');
} else {
    System.debug('This is not an integer, but a ' + i.className);
}

我找不到在文档中返回类类型的方法/属性(假设它在那里)。我错过了吗?

dynamic salesforce apex-code
7个回答
9
投票

来自p. 122 of the Apex Developer Guide

如果您需要在运行时验证对象是否实际上是特定类的实例,请使用instanceof关键字...

但是,您不能在其子类的实例上使用instanceof关键字,否则您将收到编译错误。例如:

Integer i = 0;
System.debug(i instanceof Integer);

>> COMPILE ERROR: Operation instanceof is always true since an instance of Integer is always an instance of Integer.

您只需要在超类上使用instanceof关键字。例如:

System.debug((Object)i instanceof Integer);

>> true

如果您需要有关类本身类型的信息,请检查System.Type方法(pg 396 of current Apex developer's guide。以下是一些示例:

Type integerType;
integerType = Type.forName('Integer');
integerType = Integer.class;

8
投票

今天早些时候有人问过我。这是一个更动态的解决方案。

MyClass mine     = new MyClass();
String myStr     = String.valueOf(mine);
String className = myStr.split(':')[0];
System.assertEquals('MyClass', className);

2
投票

Salesforce Apex的通用代码,用于解释:

public class Animal {}
public class Bird extends Animal {}

Animal a = new Bird();                      // Success
System.debug(a);                            // Bird:[]
System.debug((Bird)a);                      // Bird:[]
System.debug((Animal)a);                    // Bird:[]
System.debug(a instanceof Bird);            // true
System.debug((Animal)a instanceof Bird);    // true
System.debug((Bird)a instanceof Bird);      // Operation instanceof is always true since an instance of Bird is always an instance of Bird
System.debug((Bird)a instanceof Animal);    // Operation instanceof is always true since an instance of Bird is always an instance of Animal

2
投票

只是为了添加关于toString()String.valueOf()的更多信息。

不能依赖String.valueOf()在运行时获取Apex类的名称。我不认为这是记录的,但如果使用override关键字将toString()方法添加到自定义类,则String.valueOf()将使用它来确定对象的字符串值。

class MyClassDefaultToString {
}

class MyClassOverrideToString {
    public override String toString() {
        return 'override toString';
    }
}

MyClassDefaultToString c1 = new MyClassDefaultToString();
System.assertEquals('MyClassDefaultToString:[]', String.valueOf(c1));

MyClassOverrideToString c2 = new MyClassOverrideToString();
System.assertNotEquals('MyClassOverrideToString:[]', String.valueOf(c2));
System.assertEquals('override toString', String.valueOf(c2));

0
投票

不理想,但这是一种完成这项工作的方法:

public String getClassType(Object o)
{
    String retVal = 'Unknown';

    if(o instanceof Klass1)
        retVal = 'Klass1';
    else if(o instanceof Klass2)
        retVal = 'Klass2';
    else if(o instanceof Klass3)
        retVal = 'Klass3';

    return retVal;
} 

0
投票

这适合我

Map<String, Object> m =  (Map<String, Object>)JSON.deserializeUntyped(JSON.serialize(myObjectInstance));
Map<String, Object> mComplexProperty = (Map<String, Object>)m.get('complexProperty');
String mSimpleProperty = (String)m.get('simpleProperty');

我不确定JSON序列化和反序列化是否会开销,但是......现在它正在运行


0
投票

如果您需要FQCN而不是类名(例如您从Java的getName()获得的内容),该怎么办?这是你可以做的。

public class Beasts {
  public interface Animal {}
  public virtual class Bird implements Animal {}
  public class Robin extends Bird {}
}

System.assertEquals(
  Robin.class,
  Type.forName(ObjUtil.getName(new Robin(), true))
);
System.assertEquals(
  Robin.class,
  Type.forName(ObjUtil.getName((Animal)new Robin(), true)))
);
System.assertEquals(
  Robin.class,
  Type.forName(ObjUtil.getName((Bird)new Robin(), true)))
);

public class ObjUtil {
  public static String getName(Object obj, Boolean isQualifiedName) {
    // Qualified name
    if (isQualifiedName) {
      try {
        if (0 == (Long) obj) {
        }
      } catch (Exception ex) {
        typeName = ex.getMessage().remove('Invalid conversion from runtime type ').remove(' to Long');
        System.debug('typeName = ' + typeName);
        return typeName;
      }
    } else {
      // Class name
      typeName = String.valueOf(obj);
      if (typeName.indexOf(':[') != -1) {
        typeName = typeName.split(':')[0];
        System.debug('typeName = ' + typeName);
        return typeName;
      }
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.