简体   繁体   中英

Java Autoboxing/Unboxing and Generic Type issue

I'm testing my knowledge on Generics in Java, and I'm coming across an issue.

The code

return (t%2==0);

in my IsEven.java wont compile, as well as

int comparison = t.compareTo(memberT);

in my GreaterThan.java

I assume this is an error with how I set up the Generic typing of the class? Any additional help would be appreciated.

ArrayTester.java

import java.util.Arrays;


public class ArrayTester<T> {

    private T[] myArray;
    CustomTest<T> tester;

    public ArrayTester(T[] tArray, CustomTest<T> cTest)
    {
        myArray = tArray.clone();
        tester = cTest;
        Arrays.sort(myArray);
    }

    public void printIfValid()
    {
        for(int i = 0; i < myArray.length; i++)
        {
            if(tester.test(myArray[i]))
            {
                System.out.print(myArray[i] + " ");
            }
        }
        System.out.println();
    }

    public int countIfValid()
    {
        int tracker = 0;

        for(int i = 0; i < myArray.length; i++)
        {
            if(tester.test(myArray[i]))
            {
                tracker++;
            }
        }
        return tracker;
    }

}

CustomTest.java

public interface CustomTest<T> {
    public boolean test(T t);
}

AllLower.java

public class AllLower implements CustomTest<String> {

    public boolean test(String t) {
        String lowerCaseVersion = t.toLowerCase();
        return t.equals(lowerCaseVersion);
    }    
}

GreaterThan.java

public class GreaterThan<T extends Object> implements CustomTest<T> {

    T memberT;

    @Override
    public boolean test(T t) {
        int comparison = t.compareTo(memberT); //why doesnt this work?
        if(comparison == 1)
        {
            return true;
        }else{
            return false;
        }
    }

    public GreaterThan(T t)
    {
        memberT = t;
    }

}

ECTester.java

public class ECTester {

        public static void main(String[] args) {
                Integer[] intArray = {2, 8, 6, 7, 4, 10, 3, 1, 9, 5};
                Double[] dblArray = {11.9, 12.2, 5.4, 0.2, 3.3, 3.9, 4.2, 1.1, 123456.0, 10.0001};
                String[] strArray = {"Why", "is", "A", "raven", "liKe", "a", "wriTing", "desk?"};

                ArrayTester<Integer> intTest = new ArrayTester<Integer>(intArray, new IsEven<Integer>());
                ArrayTester<Double> dblTest = new ArrayTester<Double>(dblArray, new IsEven<Double>());
                ArrayTester<String> strTest = new ArrayTester<String>(strArray, new AllLower());
                ArrayTester<Integer> intCompare = new ArrayTester<Integer>(intArray, new GreaterThan<Integer>(4));
                ArrayTester<Double> dblCompare = new ArrayTester<Double>(dblArray, new GreaterThan<Double>(4.5));
                ArrayTester<String> strCompare = new ArrayTester<String>(strArray, new GreaterThan<String>("last"));

                System.out.println("There are " + intTest.countIfValid() + " valid integers");
                System.out.println("They are: ");
                intTest.printIfValid();

                System.out.println();

                System.out.println("There are " + dblTest.countIfValid() + " valid doubles");
                System.out.println("They are: ");
                dblTest.printIfValid();

                System.out.println();

                System.out.println("There are " + strTest.countIfValid() + " valid strings");
                System.out.println("They are: ");
                strTest.printIfValid();

                System.out.println();

                System.out.println("There are " + intCompare.countIfValid() + " integers greater than 4");
                System.out.println("They are: ");
                intCompare.printIfValid();

                System.out.println();

                System.out.println("There are " + dblCompare.countIfValid() + " doubles greater than 4.5");
                System.out.println("They are: ");
                dblCompare.printIfValid();

                System.out.println();

                System.out.println("There are " + strCompare.countIfValid() + " strings greater than \"last\"");
                System.out.println("They are: ");
                strCompare.printIfValid();

                System.out.println();


        }
}

IsEven.java

public class IsEven<T extends Number> implements CustomTest<T>{

    @Override
    public boolean test(T t) {
        return (t%2==0);
    }
    //Can't figure out why it wont accept this
}

Unfortunately numeric operators like % aren't available as polymorphic constructs: the type of the operands needs to be known at compile time, which means you can't use it with an arbitrary Number .

And autoboxing/unboxing only applies when going from a specific primitive wrapper type (eg java.lang.Integer ) to the corresponding primitive type (ie int ); there is no primitive counterpart of Number to unbox to.

What you can do is either use longValue() or doubleValue() to pull out a long or double that you can use % with, or possibly use an if/else chain with instanceof checks. This won't completely solve your problem because Number is an open type -- non-primitive implementations exist. ( BigInteger and BigDecimal are the well-known ones, but third-party libraries can add their own Number implementations as well.)

As for your other question about compareTo() , as mentioned in the comments above, you need T extends Comparable<? super T> T extends Comparable<? super T> to ensure that the compareTo() method exists.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM