Unfortunately, I’m not familiar enough with C# to compare it to Java in such details. I always considered these languages very similar, because they were designed to serve similar role. Now I see that there are in fact great differences between them. Don’t take my words for granted, but I believe the main priorities for Java were always reliability, being error-proof and multiplatform and many design decisions depended on them.
In Java it is impossible to even intentionally access unallocated memory or accidentally access a different location in memory than intended. It is impossible to leak any memory or mess anything in the way that VM will crash. I may miss something, but I don’t see how you could achieve such requirements while having pointers in the language.
For long time C# ran on a single OS and mostly on a single CPU architecture. Java ran on everything from the very beginning: Windows, Linux, x86, ARM. It ran on mobile phones since around 1998 - long before Android/iOS were created. There are microcontrollers capable of running Java bytecode. Each platform could work much differently, for example JVM passes function parameters on stack, while Android implementation passes them as virtual registers. And still, Java have a requirement: write once, it will just work. For example, I see that until recently the way to convert ints to byte arrays in C# was to use
BitConverter. This util is soooo-not-Java-ish. For a Java developer it is ridiculous that some function works differently depending on the CPU architecture.
So, I think that while these two languages are pretty similar, they really differ in priorities and expectations of developers. This difference results in different design choices and removing some features known from other languages. Kotlin is partially dependent on Java design, but even if it wouldn’t I guess it would still not have pointers - similarly to e.g. Python. They are just too error-prone and too low-level. They could be added in the future as a feature specific for targeting native.