Java is Pass-by-Value
This article is overly pedantic.  Java's semantics are pass-by-value only of you consider that the "values" that are being passed are pointers.  But Java doesn't have first-class pointers, it has implicit pointers.  The only thing you can do with a Java pointer "value" is to tacitly dereference it.In fact, you can write a swap(x,y) function in Java.  It goes something like this:    class foo { int value }
    
    void swap(foo x, foo y} {
      int temp = x.value;
      x.value = y.value;
      y.value = temp;
    }

(Yes, I know this isn't valid Java.  Cut me a little slack here, OK?)"But that's cheating" you protest.  "That's not swapping the value of X and Y, that's swapping the value of a slot in the values of X and Y, which happen to be objects."  Well, yeah.  So?  Compare that to this C code:  struct foo { int value }
  
  void swap(struct foo x, struct foo y) {
    [same code as above]
  }

The effect of this function will be DIFFERENT.  Specifically, the C function will have no effect while the Java function will swap the value slots of X and Y because C lets you pass a structure as a value while Java does not.  All Java "values" are (tacit) pointers to objects [1].  Pounding your fist on the table and insisting that Java is pass-by-value because you can't write a swap(x,y) function obscures this crucial difference.[1] OK, it also has ints and floats of various sizes.  But that's really it.