function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
matthew@forty2degrees.commatthew@forty2degrees.com 

Type method, need to verify class implements an interface, instanceof for interfaces?

Hi

 

I am using the new Type methods to dynamically load a class, that implements an interface.  With the aim to make the code robust, i would like to check that the class implements the interface before instantiation / casting.

 

I would like the the keyword 'instanceof' to verify a class implements an interface, as i understand it, it only verifies class type.

 

Does anyone know a good way to verifying a class implements an interface?

 

I can always try/catch around a cast, but I think this is a workaround.

 

Thanks in advance.

Matthew

 

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

So, "open mouth, insert foot." Interfaces are supported. Given:

 

global interface ABC {
  void BCD( );
}

 

global class CDE implements ABC {
  global void BCD( ) {
    System.debug( 'Okay!' );
  }
}

 

Object a = System.Type.forName('CDE').newInstance( );
System.assertEquals( true, a instanceof ABC );
System.assertEquals( true, a instanceof CDE );

 This is a welcome addition to instanceof.

All Answers

sfdcfoxsfdcfox

It appears that you can now query ApexClass. So you can do this:

 

apexclass ac = [select id,name,body from apexclass where name = :classname];
string[] bodyparts = ac.body.split('\n');
string bodydecl = '';
for( string part : bodyparts ) {
  bodydecl += part;
  if( part.indexOf( '{' ) != -1 ) {
    break;
  }
}
if( bodydecl.indexof( 'implements' ) != -1 ) {
  string implpart = bodydelc.substring( body.indexof( 'implements' )+'implements '.length() );
  implpart = implpart.replaceAll(' ','').replaceall('\\{','');
  string[] interfaces = implpart.split(',');
  set<string> interfacenames = new set<string>( interfaces );
}
if( interfacenames.contains('someinterface') ) {
  // it contains the interface
}

I think I'd rather use the try-catch block than source code parsing...

matthew@forty2degrees.commatthew@forty2degrees.com

Thanks, very interesting ....

 

I will try it, it will be interesting if you can do the apexclass query with different namespaces, i assume not.

 

So for now the try/catch approach will work.

 

As SFDC matures the Typing capabilities, i hope we can have an instanceof feature that works with interfces.

 

Thanks again.

Matthew

 

sfdcfoxsfdcfox

So, "open mouth, insert foot." Interfaces are supported. Given:

 

global interface ABC {
  void BCD( );
}

 

global class CDE implements ABC {
  global void BCD( ) {
    System.debug( 'Okay!' );
  }
}

 

Object a = System.Type.forName('CDE').newInstance( );
System.assertEquals( true, a instanceof ABC );
System.assertEquals( true, a instanceof CDE );

 This is a welcome addition to instanceof.

This was selected as the best answer
matthew@forty2degrees.commatthew@forty2degrees.com

Thanks, I worked out what i was doing wrong. instanceof does support interfaces.  I was trying to check on the Type, this does not work, so i create a instance with 'object' and then check with instanceof before casting.

Thanks again

Matthew

Andrey MaksimovAndrey Maksimov
(sorry for necro-posting)

Type.forName('CDE').newInstance() does not work if you need to check a class without no-arg constructor. if you are going to check all available classes there most likely will be one you do not maintain. the only possible answer would be Reflection, sadly there is none in APEX.