Here is my rationalization:
classOf[T]
classOf is defined in Predef as a function with this signature:
def classOf[T]: Class[T]
Although it’s implemented by the compiler, using the function syntax is possible without having to create any special treatment in terms of syntax. So that’s one reason here to consider this option.
The alternative like String.class would imply that each class has a companion object with a field class. So there are two problems:
classis a keyword, so that causes a problem where the syntax would require a special case for it- if you just create
class Awithout a companion object, it’s would be odd to be able to refer toA.class, which would be like accessing the class field on the companionA.
A.type:
On why typeOf[A] may be confusing. It looks like a function call, but types don’t live in the same world as function results (function results have types, but the type itself only makes sense at compile time). I can ascribe a type to a variable:
scala> val a: A.type = A
a: A.type = A$@c21a68
I can’t assign a type like it’s returned by a function:
scala> val b = A.type
<console>:1: error: identifier expected but 'type' found.
val b = A.type
^
On the other hand types can be member of a object:
scala> object A { type type1 = Int }
defined module A
scala> val x: A.type1 = 1
x: A.type1 = 1
So it is not a big stretch to have A.type refer to the type of object A. Note that .type aren’t used beyond referring to types of singleton objects, so it’s not really that frequent.