2

Not sure if this is a platform bug or by design feature with case insensitive variable names?, but it gave me a lot of trouble so wanted to post a question about it to document the workaround I found.

GeoCodeCensusResponse geoCodeCensusResponse = (GeoCodeCensusResponse)System.JSON.deserialize(reponseBody, GeoCodeCensusResponse.class);

system.debug(geoCodeCensusResponse);

The above code will not compile with the following error: "Variable does not exist: GeoCodeCensusResponse.class"

Only after changing the variable name am I able to save. My fix looks like the following.. changing my variable name to "test":

GeoCodeCensusResponse test = (GeoCodeCensusResponse)System.JSON.deserialize(reponseBody, GeoCodeCensusResponse.class);

system.debug(test);
4

This is expected behavior. It is strongly recommended that you do not name classes, interfaces, enums, or variables after built-in values, as it can cause compilation errors. Always use names that do not conflict with existing data types. For more information, see Namespace, Class, and Variable Name Precedence, notably:

  1. The parser first assumes that name1 is a local variable with name2 - nameN as field references.

  2. If the first assumption does not hold true, the parser then assumes that name1 is a class name and name2 is a static variable name with name3 - nameN as field references.

  3. If the second assumption does not hold true, the parser then assumes that name1 is a namespace name, name2 is a class name, name3 is a static variable name, and name4 - nameN are field references.

  4. If the third assumption does not hold true, the parser reports an error.

Rule #1 is what tripped you up: the local variable existed, so rule #2 did not get evaluated, resulting in the compilation error you experienced.

2

This issue is due to the case insensitive nature of Apex. You can reproduce it with any class name. Once you declare an instance with the same name as the class, the compiler tries to dereference the instance instead.

MyClass myClass = new MyClass();
Type myType = MyClass.class; // compile fail
// last reference to MyClass points to instance

Note that you can still get the type dynamically.

MyClass myClass = new MyClass();
Type myType = Type.forName('MyClass'); // compiles

Or you can cache the type beforehand.

Type myType = MyClass.class; // compiles
MyClass myClass = new MyClass();

Or of course, avoid the naming conflict altogether.

MyClass instance = new MyClass();
Type myType = MyClass.class; // compiles

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.