Interesting proposals: Java 9 and beyond

I’m naughty like that.

We’re making the compiler infer everything + dog, it can properly analyze arbitrarily complex control-flow and notify me of variables that are potentially null at any point i’m using the variable, but it still does not figure out the most trivial of control-flows:


if(obj instanceof String) {
   String str = (String)obj; // seriously? I have to cast here?
}

Maybe using ‘var’ here will finally resolve this 2 decade old annoyance :slight_smile:

Sorry for being offtopic.

That’s on topic!

My idea of simply using implicit casting seems to solve all the problems. You wouldn’t have to cast inside the “if” because String str = obj implies obj must be cast to a string anyway.

The diamond operator is great and works in a very similar way - you’ve already declared the type in code, visible right next to where you’re using it - why type it again.

Cas :slight_smile:

Think I found the instanceof thing I mentioned previously from the Project Coin list, although it seems more verbose than I remember.


switch (obj) instanceof {
  case String:
    // obj is now String
    obj = obj.trim();
}

Mind you, using switch suggests you’d have a chain of options, which is a real code smell! :-\

I think the biggest problem with this is that a lot of newbies are gonna accidentally cast things all the time without realizing it. Implicit casts should only be permitted when the variable is proven to be of a certain class… which probably means only in the trivial if(instanceof) --> cast case.

Actually, Project Coin proposal moved on to


if instanceof (String obj) {
  String s = obj.trim();
}

which is more like I remember. Also some examples of why using existing syntax (as @Riven) was problematic.

Anyone interested - http://mail.openjdk.java.net/pipermail/coin-dev/2009-May/thread.html

I don’t know how that’d be a problem… the compiler is simply inserting the cast for you. You have already declared the type - why repeat what you have just typed? You’ve already explicitly declared the type, right there, in code, in front of you: this means you don’t have to pointlessly repeat your declaration. Illegal casts are still illegal. Runtime CCEs are still possible. There’s just less code to look at, type, and maintain.

Cas :slight_smile:

@theagentd is right. You cannot simply make EVERY variable definition using an assigned value of an incompatible static type to be an implicit/hidden cast.
That would defer type error checking from compiletime to runtime, and you would end with dynamic languages like JavaScript…

This “var” thing is just change for change’s sake. I wouldn’t willingly use it.

I hate the if-instanceof-then-explicitly-cast-anyway pattern. How about an explicit “assign with cast” operator? Some thing like:


/*old*/ int x = (int)floatyNum;
/*new*/ int x := floatyNum;

An “assign with cast” operator like := would be trivial to implement of course and have no wider language implications.

i also think about that all time writing "instanceof ", and after i see Question here i find answer in couple sec ^^

Up:


	Object aaa = "Q";
	String s = Cast_Me(aaa, String.class);
	Integer i = Cast_Me(aaa, Integer.class);
+	Integer i2 = Cast_Me(s, Integer.class);
+	static public<E, T extends E> T Cast_Me(E Obj, Class<? super T> cl){   
		if(cl.isInstance(Obj)){
			return (T)Obj;
		}
		return null;
	}

p.s Lol i’m so good solving someone else problems XD, but not my own :frowning:

How is

String s = Cast_Me(aaa, String.class);

…better or shorter than:

String s = (String)aaa;

if wrong Instance return null)

I don’t want my reference nullified, in this case I usually want the error.

I hope you realize how & why that is really really nasty.

To the other suggestions, I favor if instanceof; it’s the one closest to ‘fixing’ the instanceof operator (it should have never been a binary operator).

Why You troll me :wink:


 static public<T> void Cast_Me(Object Obj, Class<T> cl){   
      if(cl.isInstance(Obj)){
         return (T)Obj;
      }
+      throw new IllegalArgumentException("NOooooo..");
-      return null;
   }

Yes - but there is no problems in Language or IDE for fixing this, in more flexible way)

noctarius, it’s still unclear to me how VarHandle and MemoryRegion drive sun.misc.Cleaner useless. How can I decide when I want to free the native resources used by a direct NIO byte buffer?

This!

Also, if I decide to refactor a data type for some reason, I want the compiler/IDE show me all the immediate places I break its contract, not at some obscure point far down the magic var/auto rabbit hole.

Personally I prefer the cast, or better a more explicit statement like thing.foo().asString(), for the exact same reason as above. It documents my intention as a programmer. By forcing me to write it down (to please the compiler), it forces me to think about the reason.

I just don’t want to have to write the same thing twice. Especially on the same line of code. It’s absolutely no different in concept to the diamond operator.

Cas :slight_smile:

Hmmm… I thought about it a bit, and there are quite a few differences:
First: The diamond operator can only be used with instantiations of classes of a parameterized type. There is no type error possible in that case when we use the diamond operator instead of repeating the type argument with the constructor call. (even if we forget about type-erasure for a moment, and pretend it wouldn’t happen)
Second: If the type argument of the parameterized type declaration of your variable you want to assign to would not be compatible with the type parameter of the parameterized type, then that would be a static compile-time type error.
So, with the diamond operator we never defer type checking to runtime.

EDIT: But I am totally with you, I would like to not having to cast to a type which I previously instanceof’ed.

[quote=“princec,post:118,topic:55436”]
Totally agree. Which is why I like the var/val/auto proposal. I don’t get it, how you can dislike redundancy and JEP 286 at the same time? Especially since it’s going to be applicable only to local variable declarations, not field declarations like other languages.

Both type inference and smart casts are supported (perfectly imho) in Kotlin, you can give it a try to see how it’d feel like. Needless to say, I’d love to have both in Java. Another thing that Kotlin got right is primitive casts, they are never done automatically (this sounds worse than Java, but no, it isn’t). Btw, nothing about all this requires runtime support, it’s all done statically and safely at compile time, i.e. any incompatibilities after type/cast inference are reported as compile-time errors.