Reverse an array without affecting special characters
Class fields


    static HashSet&lt;Character&gt; invalidChars = new HashSet&lt;Character&gt;(Arrays.asList(',', '?', ':','!','$'));



You might as well go ahead and make this final as well.  

    public static final Set&lt;Character&gt; invalidChars = new HashSet&lt;&gt;(Arrays.asList(',', '?', ':', '!', '$'));


As a final variable, it's clear that it won't change.  

We should probably specify a visibility.  Unless it's a secret, we should go ahead and make it public.  Since it's final, no one can change it.  

It is better to type to the interface than the implementation.  This allows us to change the implementation without changing the type.  And it forces us to limit ourselves to the operations available in the interface.  

In newer versions of Java, you don't need to say Character twice.  The compiler will figure out the type on the second one.  

Eliminate unnecessary variables


        int l = 0;
        int r = charArray.length - 1;
        for (int i = 0; i &lt; charArray.length; i++) {

            if (r &lt;= l) {
                break;
            }



You can write this either 

        for (int l = 0, r = charArray.length - 1; l &lt; r; ) {


or 

        int l = 0;
        int r = charArray.length - 1;
        while (l &lt; r) {


You don't need the extra i variable.  Nor do you need to do the l &lt; r check separately.  

It's up to you if you use a for or a while.  Either will work.  The for is a bit more compact, but you have to leave the update section blank.  Either will be shorter.  

Not really invalid


            if (!isInvalidChar(charArray[l]) &amp;&amp; !isInvalidChar(charArray[r])) {
                charArray = swapChars(charArray, l, r);
                l++;
                r--;
            } else if (isInvalidChar(charArray[l])) {
                l++;
            } else if (isInvalidChar(charArray[r])) {
                r--;
            }



It's not that the characters are invalid.  They are expected and you want to preserve them.  It's that the character are special and treated different.  Consider 

            if (isSpecialChar(charArray[l])) {
                l++;
            } else if (isSpecialChar(charArray[r])) {
                r--;
            } else {
                // neither is a special character
                swapChars(charArray, l, r);
                l++;
                r--;
            }


You use the terminology special elsewhere, so why not here?  

I also like that this emphasizes the positive.  

Since we already know that neither character is a special character, we don't have to check again.  

The swapChars method modifies the charArray in place.  We don't have to return it and assign.  

Generating a character array


        char[] charArray = new char[]{'a', 'b', 'c', 'd', '?', 'f', 's', ':', 'w'};



If you want to type less, consider 

        char[] charArray = {'a', 'b', 'c', 'd', '?', 'f', 's', ':', 'w'};


or 

        char[] charArray = "abcd?fs:w".toCharArray();


No big deal, but why type more than necessary?