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
GrrrrrrrrrrrrrGrrrrrrrrrrrrr 

Help with get; set; methods

Hi everyone.  I am trying to understand how to use the get; set; methods.  Here is my block of code:

 

public class LogoImage {

    public LogoImage(ApexPages.StandardController controller) {
        get{  return image;  }
        set{  image = value; }
    }

    // get a company logo: based on user log in, strip spaces, return image name
    public String getImageName(){     
       String file = [SELECT Name 
                        FROM Account 
                       WHERE Id IN 
                            (SELECT AccountId 
                               FROM user 
                              WHERE username=:UserInfo.getUsername()
                             )
                       LIMIT 1
                     ].Name;
       file = file.replace(' ', '');  
       String foldername = 'Logos/';
       String extension = '.jpg';
       String fullImageName = foldername + file + extension;
       return fullImageName;
    }  
}

 I am trying to understand what the Apex Developer's Guide means and I obviously don't (so say my error messages :)  )  ... Could someone please show me (in code, not links to more reading material) an example of how I would want to use the get set method?

 

I should also point out that without the get/set this works on my visualforce pages.  My partner portal users get a logo image on their page of their company when they log in.  But I want to understand gets and sets so I can write pages and classes that are ... well, not crappy.

 

Thanks!

 

 

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

Getters and Setters are accessor and mutator functions (respectively). You can use them for a variety of interesting purposes, ranging from mundane to esoteric. Here are some examples:

 

1) A list of data that might not be initialized can "smart-initialize" itself instead of returning a null value and crashing your code:

 

public Integer[ ] ages {
    get {
        if( ages == null ) ages = new Integer[ ] { };
        return ages;
    }
    set; // Default setter method, the same as: set { ages = value; }
}

You can use it as a means of auto-counting:

 

public Integer autoCount { get { return ++autoCount; } set; }

You can use it for constraints:

 

public Integer currentAge {
  get;  // default getter: get { return currentAge; }
  set { currentAge = Math.min( Math.max( value, 100 ), 0 ); }
}

You can make variables read-only, and possibly calculated:

 

public Integer currentPageNumber {
    get { return currentOffset / 25; }
// no setter }

You can make variables write-only, possibly to protect the data, or create special behavior:

 

public String addString {
  // no getter, is write only
  set { buffer.add( value ); }
}

This creates a variable addString that would add a string assigned to it into a buffer object (presumably a set or list), e.g.:

 

addString = "Hello, ";
addString = "World.";
// Buffer is now { "Hello, ", "World." }

You do need to be cognizant of certain limitations, like a setter for A shouldn't call a getter for B, if B's getter would call A's setter (e.g. infinite loop), getters and setters are not called in any particular order, and so should not rely on any other getter or setter having been called beforehand. Each getter and setter should use only private members or their own variable's data, and the former usage shouldn't rely on the order of getters or setters having been called.

 

In your code example, you could do the following:

 

public String imageName {
  get {
    if( imagename == null ) {
       String file = [SELECT Name 
                        FROM Account 
                       WHERE Id IN 
                            (SELECT AccountId 
                               FROM user 
                              WHERE username=:UserInfo.getUsername()
                             )
                       LIMIT 1
                     ].Name;
       file = file.replace(' ', '');  
       String foldername = 'Logos/';
       String extension = '.jpg';
       imageName = foldername + file + extension;
    }
    return imagename;
  }
}

I've got to leave for right now, but feel free to ask more questions, we'd be glad to help out.

All Answers

sfdcfoxsfdcfox

Getters and Setters are accessor and mutator functions (respectively). You can use them for a variety of interesting purposes, ranging from mundane to esoteric. Here are some examples:

 

1) A list of data that might not be initialized can "smart-initialize" itself instead of returning a null value and crashing your code:

 

public Integer[ ] ages {
    get {
        if( ages == null ) ages = new Integer[ ] { };
        return ages;
    }
    set; // Default setter method, the same as: set { ages = value; }
}

You can use it as a means of auto-counting:

 

public Integer autoCount { get { return ++autoCount; } set; }

You can use it for constraints:

 

public Integer currentAge {
  get;  // default getter: get { return currentAge; }
  set { currentAge = Math.min( Math.max( value, 100 ), 0 ); }
}

You can make variables read-only, and possibly calculated:

 

public Integer currentPageNumber {
    get { return currentOffset / 25; }
// no setter }

You can make variables write-only, possibly to protect the data, or create special behavior:

 

public String addString {
  // no getter, is write only
  set { buffer.add( value ); }
}

This creates a variable addString that would add a string assigned to it into a buffer object (presumably a set or list), e.g.:

 

addString = "Hello, ";
addString = "World.";
// Buffer is now { "Hello, ", "World." }

You do need to be cognizant of certain limitations, like a setter for A shouldn't call a getter for B, if B's getter would call A's setter (e.g. infinite loop), getters and setters are not called in any particular order, and so should not rely on any other getter or setter having been called beforehand. Each getter and setter should use only private members or their own variable's data, and the former usage shouldn't rely on the order of getters or setters having been called.

 

In your code example, you could do the following:

 

public String imageName {
  get {
    if( imagename == null ) {
       String file = [SELECT Name 
                        FROM Account 
                       WHERE Id IN 
                            (SELECT AccountId 
                               FROM user 
                              WHERE username=:UserInfo.getUsername()
                             )
                       LIMIT 1
                     ].Name;
       file = file.replace(' ', '');  
       String foldername = 'Logos/';
       String extension = '.jpg';
       imageName = foldername + file + extension;
    }
    return imagename;
  }
}

I've got to leave for right now, but feel free to ask more questions, we'd be glad to help out.

This was selected as the best answer
GrrrrrrrrrrrrrGrrrrrrrrrrrrr

sfdcfox,

 

This is wonderful!  Thank you.  I do have a couple of questions though.

 

1.  If I am using the ImageName method many times in different classes and VF pages, I thought it would be best to split this out into its own class so I dont have to keep writing the same thing each time (we have a lot of partner portal users, and no signs of slowing down any time soon).  In this case, I have tried to write the test method seperate, but with no success.  I can post the attempted test methods.  But I am not sure if  get/set makes the test code verbiage different.  Does it?

 

2.  Would it be best common practice to initiate the set; to value even though it is default, or is that just a waste of time / code?

 

3.  I have been writing all my classes thus far as this:  "public class getAllRecords", or "public with sharing class getLogoImage" and I have been writing all my methods the same (getImageName, or getClosedWon) etc.  If I start using get/set in my classes, how does that change what I have been doing?  Can I rewrite these so they are more effective?  (In other words can I graduate from sloppy to sophisticated ?)

 

I will mark the previous answer as the solution because it does help me with some of the questions that I have over get and set.  I would still love all the help I can get to improve my skills.

 

Thanks!

sfdcfoxsfdcfox

1.  If I am using the ImageName method many times in different classes and VF pages, I thought it would be best to split this out into its own class so I dont have to keep writing the same thing each time (we have a lot of partner portal users, and no signs of slowing down any time soon).  In this case, I have tried to write the test method seperate, but with no success.  I can post the attempted test methods.  But I am not sure if  get/set makes the test code verbiage different.  Does it?

 

I've actually done this in a project. We have a set of PDFs that are rendered, but use some common logic, such as a logo file that is specified by the administrator, etc. You can use the class as an extension class, or you can make it a base class that the other portal controllers inherit from, depending on if the logic needs to communiate with the primary controller.

 

The first method looks like this:

public class SharedLogic {
  public SharedLogic( ApexPages.StandardController controller ) {
    // controller contains the page's record.
  }

  public String function1( ) {
    // return a string common to all pages
  }
}

While the second one looks like this:

 

public class BaseController {
  public BaseController( ) {
    // default initialization here
  }

  public String function1( ) {
    // return a string common to all classes
  }
}

 

public class SpecializedController extends BaseController {
  public SpecializedController( ) {
    super( ); // Call the base constructor; must be first function
    // do more initialization here
  }

  public String function2( ) {
    // This returns a string specific to this controller
  }

  // We can also call function1( ) from within this class.
}

 

2.  Would it be best common practice to initiate the set; to value even though it is default, or is that just a waste of time / code?

 

I would say that you should use custom accessors and mutators only if necessary. While the difference is minimal in terms of resources, I think that default setters and getters are preferable because they make the code easier to read. This is more a matter of preference, but do keep in mind that you have a limit to how much code you can use (3,000,000 characters total, and 1,000,000 per class), which seems like a lot, but using excessive code reduces the space you have left over for other functions. As a developer, you should strive for efficiency as much as possible.

 

3.  I have been writing all my classes thus far as this:  "public class getAllRecords", or "public with sharing class getLogoImage" and I have been writing all my methods the same (getImageName, or getClosedWon) etc.  If I start using get/set in my classes, how does that change what I have been doing?  Can I rewrite these so they are more effective?  (In other words can I graduate from sloppy to sophisticated ?)


The most important change would be your test methods; instead of calling a function, you access the member directly, which in turn calls the functions you've written. Using getX/setX functions instead of setters and getters likely increases the size of your code, although the difference is marginal. A major feature of using accessors and mutators is that it forces you to place the getters and setters next to each other, instead of potentially being spread throughout the class. Generally speaking, this feature means that your code's readability is improved, but excessively large getters and setters might actually decrease readability. If your function is larger than about 20 lines or so, consider using getX/setX functions instead, but do remember to keep them next to each other so they're easy to find.

 

If you have the time, consider using classes with inheritance or extension classes. They will make your code more manageable by localizing common features.

 

As some examples...

 

We have several pages that allow users to select from "sites", which will update the address fields for the record. The fields are dynamically mapped using a custom class that provides field mapping services for each of our custom objects. In this way, the address copying logic is reduced to a single instance instead of approximately 10 different classes, which provides a significant space savings. If any one page isn't working correctly, we can be certain that it is because our field mapping class is using the wrong fields, while if all pages are working incorrectly in regards to this feature, we can be certain that fixing the logic once will correct all of the pages.

 

We have several different types of "line items" that behave similarly to OpportunityLineItem, including using PricebookEntry Id values, discounts, and so on. Again, if a single type of object is behaving incorrectly, we know it is because of the field mapping, while if the logic affects all of our custom objects, we know which file to look at.

 

We also have various pages that have essentially the same function (editing a single line item record), but with slightly different logic in place for the various types of objects. In this case, we have a common class that contains the logic shared between all the different types of line items, plus some specialty classes that handle the distinct differences between the different types of line items. This particular use case shaved nearly 60kb of source code from our project.

 

In conclusion, I would say there are many types of tools available in Apex Code, and learning how to use each effectively is the key to elegant coding.

Priya ParabPriya Parab
Hi Sfdcox,

I want to use getter setter for List of wrapper class.

Controller class : 
public class demoClass {

public List<demoWrapper> resultList1 {get;set;}
public List<demoWrapper> resultList2 {get;set;}

public List<demoWrapper> testRecords{
    	get{
    		if(..some condtion..){
    			return resultList1;
	    	}
	    	else{
	    		return resultList2;
	    	}
    	}
    	set{
			testRecords= value;
    	}
    }
}
Wrapper Class :
 
public class demoWrapper {

      public Boolean checkbox   {get;set;}
      public Boolean string1    {get;set;}
}

VF Page : I want to use testRecords wrapper list in page block table.
I want to get the updated list for further processing.
Getter method is working as I get values in the page block table.
But if I check the checkboxes then I am not getting the updated value (checkbox = true).
<apex:page controller="demoClass ">
<apex:form id="form1" >
<apex:pageblockTable value="{!testRecords}" var="wrap">
     <apex:column>          
           <apex:inputcheckbox value="{!wrap.checkbox}"/>                       
     </apex:column>
     <apex:column value="{!wrap.string1}">
</apex:pageblockTable>
</apex:form>
</apex:page>
what is wrong with the setter method? 
 
Fred Kampf 3Fred Kampf 3
Oriya, I know this is old but I was wondering if you resolved your issue?  Thanks!