Q:

When we are allowed to use "new" keyword in Java and how to use it?

As far as I know, new keyword is used to instantiate classes. And I think we need to call the class constructor and pass its arguments after this keyword. Right?
Okay, Here is a code snippet:
public class JavaApp{

    public static void main(String[] args) {
        String st1 = "Test";
        String st2 = new String("Test");

        byte[] b1 = {'a', 'b'};
        byte[] b2 = new byte[]{'a', 'b'};
        byte[] b3 = new byte[]('a','b'); //Error

        byte b4 = 3;
        byte b5 = new byte{3}; //Error
        byte b6 = new byte(3); //Error

    }

}

My questions:

What's the difference between st1 and st2?
Why we must pass the arguments of constructor in {} instead of (), in the b2 declaration line?
Why I receive error for b5 and b6?

A:

st1: This stores a reference to the object representing "Test" in variable st1.
st2: Here a new object of java.lang.String is created but it is unnecessary: it shares the value of the constructor argument and copies the hash value. (Not useful.)
b1, b2: That's the way the syntax is defined for array initializers. Probably a good reason if you study the syntax in depth.
A simple type has no object, hence no reason or possibility for new, which instantiates objects from classes (not classes, strictly speaking).

A:

st1 and st2 are two different object; first one reside inside String-Pool and second one as normal java object locates at Heap memory.
{} is not calling constructor, its just a syntax to initialize array.
byte is not a class; its a primitive type so there is no constructor for byte.

A:

Your first answer can be found in the JavaDoc of of constructor String(String)
/**
 * Initializes a newly created {@code String} object so that it represents
 * the same sequence of characters as the argument; in other words, the
 * newly created string is a copy of the argument string. Unless an
 * explicit copy of {@code original} is needed, use of this constructor is
 * unnecessary since Strings are immutable.
 *
 * @param  original
 *         A {@code String}
 */

2nd issue, these are arrays of primitives, your are not invoking a "constructor" in the same way as you would be say new Horse("Alan"). The brace notation is just an initializer which takes a list of values which Java uses to populate the array. new byte[]() concept simply does not exist in the Java language in the way you might think it does.
byte[] b2 = new byte[]{'a', 'b'};
byte[] b3 = new byte[]('a','b'); //Error

3rd issue, byte is not an object, it is a primitive, it has no constructor to call.
byte b5 = new byte{3}; //Error
byte b6 = new byte(3); //Error

However you can use the Byte object wrapper, essentially an Object version of the byte primitive, this does have a constructor.
byte b7 = new Byte((byte)3);

