简体   繁体   中英

Is it possible to have Runtime type mismatch in Java?

I am reading up OCaml and from wiki, it says:

*its static type system renders runtime type mismatches impossible*

I understand why, but then I think, why is this so special in OCaml (and FP)? How do you cause a runtime type mismatch in, say, Java? eg

boolean a = true;
int b = a + 1;

will return an error in compile time.

EDIT 1:

Haskell

func :: Int -> Bool
func i = if i > 0 then True else False

Java

boolean func (int i) {
    if (i > 0) return true; else return false;
}

Isn;t it the case that both will guarantee the argument type when the func is called?

In Java, you can cause a Runtime type mismatch like this:

Object i = Integer.valueOf(6);
String s = (String) i;   
System.out.println(s);

This will compile, because the compile-time type of i ( Object ) is allowed to be cast to String , however at Runtime, the actual value of i ( 6 , as Integer ) will be incompatible to String .

Given this, a ClassCastException is thrown.

Consider the following code using arrays:

// create an array of strings
String[] strings = new String[10];

// cast it to an array of objects
Object[] objects = strings;

// insert an object into the array
objects[0] = new Object();     // Run-time error occurs here

Java allows this to compile, despite the fact that casting a array of strings to an array of objects array introduces the possibility of run-time errors. Line 8 demonstrates this, causing a run-time exception of a type created specifically for this situation: java.lang.ArrayStoreException: java.lang.Object .

See Java generics and type erasure

That wiki is discussing static type systems in general, and contrasting them with dynamically-typed languages rather than other statically-typed languages. There's nothing specific to OCaml or Haskell about runtime type mismatches that doesn't apply to all statically-typed languages.

Note that impossible is a little disingenuous. Pretty much all statically-typed languages give you the ability to also do runtime typing in a limited way, because certain tasks are extremely difficult without it. In fact, the very paragraph you're quoting lists a couple of those cases, like serialization. Other answers here have provided some good examples in Java. However, the vast majority of your code should be able to easily avoid runtime type mismatches.

In Java, type mismatches are possible. For example, the following throws a ClassCastException .

Object o = 1;
String s = (String) o;

However, the arguments passed to a method are checked by the compiler.

It is impossible to invoke a method with signature

boolean func (int i) 

unless i is an int , and it is impossible to invoke a method with signature

boolean func2 (String s)

unless s is a String or null .

Therefore you will never get a ClassCastException at runtime within the body of func2 because s is not a String .

In Java, it is impossible to have a type mismatch between reifiable types (primitive types, non-generic reference types, raw types, types parameterized by all wildcards, or array types whose element type is reifiable).

If you have a variable of a reifiable type, then the value it holds at any point in time is guaranteed to be a value of that type. For reference types, this means that the reference is either null or points to an object whose runtime class is a subtype of the variable's type. This is guaranteed because Java requires a cast when storing a value whose type is not a subtype of the variable's type, and casts to reifiable types are checked casts , which means they are checked at runtime, and if the type is not compatible it will throw an exception rather than let there be a type mismatch.

On the other hand, for non-reifiable types (eg parameterized types), it is possible to have a type mismatch (which is called "heap pollution" in Java terminology). This is because casts to non-reifiable types are unchecked casts .

List<String> foo = new ArrayList<String>();
foo.add("hi");
List<?> bar = foo;
List<Integer> baz = (List<Integer>)bar; // unchecked cast
// now there is a type mismatch 

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