That's a long, long conversation to be had.
I'll just point you in the right direction here, but you need to work this out for yourself to really understand and internalize it.
One reason is that getters and setters allow you to protect yourself. You control what happens when the variable is modified.
You could, for example, decide to refuse some values - maybe your field needs to be a positive int, say. You cannot trust callers to respect that constraint (rule 1 of programming, do not trust anyone) and need to enforce it, possibly with an assertion.
A setter allows you to validate the value before actually modifying it. Direct access lets callers put illegal values in your class outside of your control - and since it can happen, it will happen.
Another reason is abstraction: if you expose the field, you're stuck with your representation forever. You might find a better, more optimal representation later, but you cannot change it since you've given callers direct access to your field - they now rely on its type.
Hiding the implementation details behind getters and setters, on the other hand, allows you to change your internal representation without breaking your external contracts - just modify the getter and no one ever needs to know.