6

This problem comes up when you try to remove clutter from names because Apex is case insensitive so xyz and Xyz are not distinguishable:

public class Xyz {
    ...
    private static Xyz[] query(...) {
        ...
    }
}

public class MyController {

    public String xyz {get; set}

    private void someMethod() {
        // Won't compile as the xyz property hides the Xyz class name
        ... Xyz.query(...);
        ...
    }
}

For built in classes adding a System. prefix allows the class to be identified and for SObjectType and SObjectField adding a Schema. prefix allows the type to be identified.

I do not think there is anything of this nature for locally added classes but want to be sure. Is there?

(For namespaced code the namespace prefix can be added but that leaks the namespace into the source code which is not ideal.)

Edit: Originally I illustrated this with an inner class but should not have and have changed that. My problem is with top-level classes.

  • I've put an (unsatisfactory) update in my answer. – rael_kid Jul 2 '18 at 12:57
  • @rael_kid Thanks. Sorry to not be clear in the original question. +1 from me. – Keith C Jul 2 '18 at 12:59
  • Don't worry, it makes the answer a bit more helpful to some people, I guess. Thanks :) – rael_kid Jul 2 '18 at 13:13
7

You should be explicit when referencing the fields or types. Like you said yourself, Apex is case insensitive, so it's extra important to use the class name when referencing inner classes or static members and to use this when referencing instance variables or methods. Besides, I think it's good practice to avoid naming collisions like this whenever you can.

public class MyController {

    public class Xyz {
        private static Xyz[] query() {
        }
    }

    public String xyz {get; set}

    private void someMethod() {
        //use MyController.Xyz to tell Apex you're referencing the inner type
        MyController.Xyz.query();
        //use this to show that you're referencing the instance variable.
        this.xyz = 'nice string';
    }
}

Edit; to elaborate a bit more on the problem concerning top level classes; the only way to access the top level class after declaring the instance variable is to use the local namespace. So you're in trouble if there is none, or if you want your code do be distributable between orgs. I would definitely suggest to change the variables name or to change the class name so there is no collision, although that could be problematic as well.

  • Good point for the inner class case. I've changed the code in the question to reflect my real problem area which isn't with inner classes. Adding this everywhere is not something I'm in favour of. – Keith C Jul 2 '18 at 12:29
  • 1
    Ah, this is interesting.. I'm afraid there's no way around this, other than using your local namespace... That will definitely hurt portability though. I think a better solution would be to change the local variable name or the name of the class (the former is probably easier). – rael_kid Jul 2 '18 at 12:38

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.