Using public variable can cause setting wrong values to the variable as the input value cannot be checked.
eg:
 public class A{
    public int x;   // Value can be directly assigned to x without checking.
   }
Using setter can be used to set the variable with checking the input. Keeping the instance varibale private, and getter and setter public is a form of Encapsulation
getter and setter is also compatible with Java Beans standard, 
getter and setter also
helps in implementing polymorphism concept
eg:
public class A{
     private int x;      //
      public void setX(int x){
       if (x>0){                     // Checking of Value
        this.x = x;
       }
       else{
           System.out.println("Input invalid");
         }
     }
      public int getX(){
          return this.x;
       }
Polymorphic example: We can assign Object Refernce Variable of the Sub type as Argument from Calling method to the Object Refernce Variable of Super Class Parameter of the Called method.
public class Animal{
       public void setSound(Animal a) {
          if (a instanceof Dog) {         // Checking animal type
                System.out.println("Bark");
             }
         else if (a instanceof Cat) {     // Checking animal type
                 System.out.println("Meowww");
             }
         }
      }