I need a quick approach to something like:
MyClass mc = new MyClass();
String theName = ClassNameProvider.getName(mc); // returns 'MyClass'
I need a quick approach to something like:
MyClass mc = new MyClass();
String theName = ClassNameProvider.getName(mc); // returns 'MyClass'
I think your requirement falls in the gap for apex but we have the ability to do one of following things:
We can retrieve the name of an object using code such as
String name = MyClass.class.getName(); //returns MyClass
We can check whether the instance of a particular type using
Boolean isSame = mc instanceof MyClass; //returns true
Or if we want to get the name from an instance of an unknown type we can do:
String name = String.valueOf(mc).split(':')[0];//returns MyClass
Hopefully one of those covers your need. See the discussion to a similar question here for more info.
String.valueOf(mc).split(':')[0] will not include the top level class for inner classes
– NSjonas
Oct 10 '16 at 18:15
String.valueOf(mc) returns the toString() value of the class. The default return value is format of ClassName:[field1=value1, field2=value2,...fieldN=valueN] but if the class overrides the toString() method then this trick may not work for you.
– Doug Ayers
Jun 22 '18 at 04:54
String name = String.valueOf( mc ).substringBefore( ':' ) as it's just a little bit clearer
– Rob Baillie
Nov 07 '19 at 11:42
This is an interesting hack as posted on the idea Method to get the Type of an Object (also Primitive Type not only SObject) by Robert Strunk:
public static String getObjectType(Object obj){
String result = 'DateTime';
try{
DateTime typeCheck = (DateTime)obj;
}
catch(System.TypeException te){
String message = te.getMessage().substringAfter('Invalid conversion from runtime type ');
result = message.substringBefore(' to Datetime');
}
return result;
}
The parse conversion exception approach overcomes the caveat that using String.valueOf(obj).split(':')[0] does not work in scenarios where the Apex class' toString() method has been overriden and returns a value in a different format, as pointed out in this comment.
String.valueOf(obj) method because it includes the top-level class for inner classes.
– Jason Clark
Jan 16 '23 at 22:18
To answer the title of the question: to get the name of the class from within any class use this:
String CurrentClassName = String.valueOf(this).substring(0,String.valueOf(this).indexOf(':'));
String.valueOf(mc).split(':')[0] among other approaches. This approach is just a slower version of that (you take String.valueOf twice).
– Adrian Larson
Apr 07 '17 at 13:17
While my response might be a delayed, it could help for someone currently in search of this solution.
Usage :
ClassUtility.getClassName(); // will return the class name from where we are calling
ClassUtility.getMethodName(); // will return the method name from where we are calling
ClassUtility.getMethodNameByLevelup(1);
ClassUtility.getMethodNameByLevelup(1);
Class :
/**
* Company: Kloudflex.com
* Purpose: A utility class for extracting class and method names from the stack trace.
* Author: Mohamed Thameem
*
* Change Log:
* 01/11/2024 - Initial Version of the class
*/
public class ClassUtility {
/**
* Gets the class name from the stack trace.
* @return String - The class name.
*/
public static String getClassName() {
List<String> splitClassList = getClassOrMethodName(0);
return (splitClassList != null) && splitClassList.size() > 1 ? splitClassList[1] : 'Unavailable';
}
/**
* Gets the method name from the stack trace.
* @return String - The method name.
*/
public static String getMethodName() {
List<String> splitMethodList = getClassOrMethodName(0);
return (splitMethodList != null) && splitMethodList.size() > 2 ? splitMethodList[2] : 'Unavailable';
}
/**
* Gets the class name from the stack trace by moving up a specified number of levels.
* @param levelUp - The number of levels to move up in the stack trace.
* @return String - The class name.
*/
public static String getClassNameByLevelup(Integer levelUp) {
List<String> splitClassList = getClassOrMethodName(levelUp);
return (splitClassList != null) && splitClassList.size() > 1 ? splitClassList[1] : 'Unavailable';
}
/**
* Gets the method name from the stack trace by moving up a specified number of levels.
* @param levelUp - The number of levels to move up in the stack trace.
* @return String - The method name.
*/
public static String getMethodNameByLevelup(Integer levelUp) {
List<String> splitMethodList = getClassOrMethodName(levelUp);
return (splitMethodList != null) && splitMethodList.size() > 2 ? splitMethodList[2] : 'Unavailable';
}
/**
* Gets the class or method name from the stack trace by moving up a specified number of levels.
* @param levelUp - The number of levels to move up in the stack trace.
* @return List<String> - The list containing class and method names.
*/
private static List<String> getClassOrMethodName(Integer levelUp) {
levelUp = levelUp == null ? 0 : levelUp;
try {
Integer a;
a = a + 1;
} catch (Exception e) {
List<String> splitStackTrace = e.getStackTraceString().split('\n');
String traceString = (splitStackTrace.size() > (2 + levelUp)) ? splitStackTrace[(2 + levelUp)] : null;
return (traceString != null) ? traceString.split(':').size() > 0 ? traceString.split(':')[0].split('\\.') : null : null;
}
return null;
}
}