The purpose of static varriables is that you don't need to create an actual instance of a class to access them. In your example class, varriable 'joe' would be the same for every instance of the class. So for example if you did this:
thing thing1 = new thing();
thing thing2 = new thing();
In that case, thing1's 'joe' would point to the same int[][] array as thing2's joe, so altering the array in one instance would affect the other and vice versa.
Another useful thing about static varriables is that if they are public, then you don't need an actual instance of the class to access them. For example, in your example class if you made 'joe' a public static int[][], then it could be accessed from anywhere in your program like this without ever creating a new 'thing' object:
thing.joe = new int[20][20];
Static varriables are really useful to use for global settings. For example, in my SoundSystem library, the class 'SoundSystemConfig' uses static varriables in this way. In that case, I made the static varriables themselves private, and made public static synchronized methods for accessing them.
Maybe a good way to think of static varriables is like there is just one instance of a class in the whole program. If you think of it from that perspective, you can see they are not really that much different than regular varriables. They still act as a handle to some set of data, and they follow all the same rules for Java varriables. Only difference is there is only one copy of each static varriable, and it exists whether or not the class was instantiated in the program.