As we know, primitive types are not object in java, for them there are overloaded stream()method in Arrays class. Suppose here just consider int. If we pass int[] then stream(int[] array) getting called and returns IntStream object.
If you go and see IntStream class then you will find only one toArraymethod, which doesn't accepting any arguments. 
So, we can't do toArray(int[]::new).
int[] in1 = {0, 0, 2, 0, 3};
 int[] in2 = Arrays.stream(in1).filter(x -> x != 0).toArray();
But for any Reference type array, we can convert to specific type.
e.g
String[] str2 = {"a","b",null,"c"};
    String[] strArr = Arrays.stream(str2).filter(i -> !=null).toArray(String[]::new);
    for (String string : strArr) {
        System.out.println(string);
    }
In the Reference type case, a generic stream method gets called from Arrays class and produces Stream<T>, now Stream interface has two overloaded toArray().
If we use 
toArray() then yield Object[], in this case we need to caste. 
toArray(IntFunction<A[]> generator) then give us A[], where A is any reference type. 
See below example
package test;
import java.util.Arrays;
public class EliminateZeroFromIntArray {
public static void main(String[] args) {
    int[] in1 = {0, 0, 2, 0, 3};
    int[] in2 = Arrays.stream(in1).filter(x -> x != 0).toArray();
    for (int i : in2) {
        System.out.println(i);
    }
    String[] str = {"a","b",null,"c"};
    Object[] array = Arrays.stream(str).filter(i -> i !=null).toArray();
    for (Object object : array) {
        System.out.println((String)object);
    }
    String[] str2 = {"a","b",null,"c"};
    String[] strArr = Arrays.stream(str2).filter(i -> i !=null).toArray(String[]::new);
    for (String string : strArr) {
        System.out.println(string);
    }
}
}