I don't understand why a static method can't use non-static data. Can anybody explain what the problems are and why we can't do it?
In most OO languages, when you define a method inside a class, it becomes an Instance Method. When you create a new instance of that class, via the new keyword, you initialize a new set of data unique to just that instance. The methods belonging to that instance can then work with the data you defined on it.

Static Methods, by contrast, are ignorant of individual class instances. The static method is similar to a free function in C or C++. It isn't tied to a specific instantiation of the class. This is why they cannot access instance values. There's no instance to take a value from! 

Static Data is similar to a static method. A value that is declared static has no associated instance. It exists for every instance, and is only declared in a single place in memory. If it ever gets changed, it will change for every instance of that class. 

A Static Method can access Static Data because they both exist independently of specific instances of a class.

It might help to look at how you invoke a static method, compared to a instance method. Let's say we had the following class (using Java-like pseudocode):

class Foo {
    // This static value belongs to the class Foo
    public static final string name = "Foo";

    // This non-static value will be unique for every instance
    private int value;

    public Foo(int value) {
         this.value = value;
    }

    public void sayValue() {
        println("Instance Value: " + value);
    }

    public static void sayName() {
        println("Static Value: " + name);
    }
}

Foo foo1 = new Foo(10);
Foo foo2 = new Foo(20);

foo1.sayValue(); // Prints "Instance Value: 10" - called on foo1
foo2.sayValue(); // Prints "Instance Value: 20" - called on foo2

Foo.sayName(); // Prints "Static Value: Foo" - called on Foo (not foo1 or foo2)


Update

As COME FROM points out in the comments, a static method is capable of working with non-static data, but it must be passed explicitly. Let's assume the Foo class had another method:

public static Foo Add(Foo foo1, Foo foo2) {
    return new Foo(foo1.value + foo2.value);
}


Add is still static, and has no value instances of its own, but being a member of the class Foo it can access the private value fields of the passed-in foo1 and foo2 instances. In this case, we're using it to return a new Foo with the added values of both passed-in values.

Foo foo3 = Foo.Add(foo1, foo2); // creates a new Foo with a value of 30

