3

The following code is valid:

List list = new ArrayList();
list.add(1);

This is because compiler make boxing/unboxing automatically.
My question is: can I somehow get compilation (or runtime) error in such situation?

I already try:
1) method that return primitive:

int foo(){
    return 2;
}

list.add(method());

2) anonymous class from java 8:

list.add(((Function) (ignored) -> 3).apply(""));

UPD:
We can parametrize List to List<Object> or even to List<Integer> the result will be the same - it's work. My question is "how can I fool autoboxing mechanism?"

Dmitry Zaytsev
  • 23,650
  • 14
  • 92
  • 146
Vova Yatsyk
  • 3,245
  • 3
  • 20
  • 34
  • 3
    What objects do you want to allow inserting into the List? – Eran Dec 07 '16 at 11:33
  • You can always add anything to `List` AFAIK. – Tim Biegeleisen Dec 07 '16 at 11:37
  • If you use generics instead of [raw types](http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it) then at least you would get an error if it was, for example, a `List` instead of a `List`. (You should not use raw types anyway, see the link). – Jesper Dec 07 '16 at 11:38
  • @Eran , I can't answer to your question, because I haven't any problem working with generics, my question is theoretical – Vova Yatsyk Dec 07 '16 at 12:57
  • `List` can hold any object, `List` can hold `Integer` and `int`, the latter through boxing. What do you have in mind here? – Tim Biegeleisen Dec 07 '16 at 13:14
  • @Jesper I update my question. You are right that we need to use generics, but it was out of scope of my question, because my code is work and I ask how to break it) – Vova Yatsyk Dec 07 '16 at 13:15
  • @TimBiegeleisen "List can hold any object" yes! And `int` isn't Object it's primitive, and I want to see some error when I pass `int` to `List` – Vova Yatsyk Dec 07 '16 at 13:18
  • Just to clarify - you want this to work `list.add(new Integer(1))` but not this `list.add(1)`? – Dmitry Zaytsev Dec 07 '16 at 13:20
  • 1
    an `int` is a primitive that will be autoboxed into `Integer` for this insertion. Simply because the JVM will try to match `add(int)` but can't, so it will convert it into `Integer` to search for `add(Integer)` and that will be possible because you have a List so `add(Object)` match – AxelH Dec 07 '16 at 13:21
  • 2
    The only way to fool the autoboxing mechanism seems to be using old java versions: http://stackoverflow.com/questions/26568608/possible-to-disable-java-autoboxing – Marco A. Hernandez Dec 07 '16 at 13:23
  • There is no way to explicitly turn off auto-boxing. But why would you want to do this anyway? – Jesper Dec 07 '16 at 13:28
  • @DmitryZaitsev yes. But it is not a pretension to Java, I like this autoboxing. I would like to know about exceptions from "auto"-boxing – Vova Yatsyk Dec 07 '16 at 13:30

2 Answers2

2

You won't fool typing system, but you can always fool the reader of your code (don't try this at home)

class MyList implements List<Integer> {

    // ...

    @Override
    public void add(Integer value) {
        // Call actual implementation
    }        

    // Overload
    public void add(int value) {
        throw new RuntimeException("No autoboxing allowed!");
    }

}

Another way to achieve similar effect would be by creating your own wrapper-type and using it as list parameter instead:

public class IntValue {

    public final int value;

    public IntValue(int value) {
        this.value = value;
    }

}

// ...

List<IntValue> list = new ArrayList<>();
list.add(new IntValue(1)); // will compile
list.add(1); // won't compile
Dmitry Zaytsev
  • 23,650
  • 14
  • 92
  • 146
  • Makes no sense at all. `List myList = new MyList(); myList.add(2)` - oops! – kan Dec 07 '16 at 15:39
  • @kan true, it will only work if you'll use `MyList list = new MyList()`. Nevertheless, that's how I understood question of OP - show some way in which `someList.add(1)` will fail. – Dmitry Zaytsev Dec 07 '16 at 15:50
  • Yeah, but enforcing use of only `MyList` is not simpler problem than the problem in the question. I.e. Now instead of forbidding `myList.add(2)` you also need to forbid using `List`. – kan Dec 07 '16 at 15:54
  • You're right, but honestly - I don't see any practical benefit of using `MyList` whatsoever. So, I approached question more like a programming puzzle. Nevertheless, I added a more practical solution for the problem to my answer. – Dmitry Zaytsev Dec 07 '16 at 16:10
0

You cannot fool compiler, it is in Java Language Spec. Apparently it's possible to use some code check-tools such as PMD or findbugs, e.g.: http://findbugs.sourceforge.net/bugDescriptions.html#BX_BOXING_IMMEDIATELY_UNBOXED and probably you could write additional custom rule for it to check your specific situations.

kan
  • 28,279
  • 7
  • 71
  • 101