Skip to main content

"string" primitive

72 replies [Last post]
luke_f
Offline
Joined: 2005-07-27
Points: 0

along similar lines to the post on c# nullable types. what would be the disadvantage of adding a string primitive?

ie:
string s = "test";
if (s == "test")
System.out.println ("is equal");

I would consider it more a convenience function. I know there are:

.equals(String)

but 9/10 times when I want to compare strings I am doing an value comparison, not object comparison.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
podlesh
Offline
Joined: 2004-07-26
Points: 0

> > It's true that primitive types in Java breaks
> "pure
> > OOP". That's Java - if you don't like it, use
> > Smalltalk or CLOS.
> Pure OOP would be nice, but value types with
> autoboxing comes pretty close.

It's pretty close when it comes to simplicity of using (which is one of benefits of pure OOP design), but sacrifices ther main benefit of primitive types (speed and memory efficiency).

> > > Just look at the problems that occur with
> > > the introduction of autoboxing in Java.
> > Yes, autoboxing (or tather autounboxing) was very
> > bad idea.
> Autoboxing works better in C#.

I should correct my statement: Autoboxing/autounboxing [i]in Java[/i] was bad idea.

> If two objects are equal
> it means they can replace each other, they can even
> be the same object in the JVM. It doesn't matter as
> long as you can compare them using an equality
> operator.
Look at method (source code) String.substring(). String made this way is immutable, it may be equal to other (simple) string, but it won't be the same at all!

---------------------------------------------------------
> For immmutable types object equality and
> identity is the same.

Identity equality was made part of Java because it allows programmer to optimize for speed. It's mostly obsolete in the era of JIT compilers and 64bit processors, but there are still some Java running on slow, memory-limited devices without JIT (embedded, J2ME). And using == instead of equals can make huge difference! (And no, autoboxing is not solution: it can be even worse).

Operator overloading is entirely different case: all arguments against it is still valid and they will always be. All the time some people want to add it, while others absolutely deny the very idea.

fuerte
Offline
Joined: 2004-11-22
Points: 0

[code]
public class string extends String {
@operator(equals)
public static boolean operatorEquals(string s1, string s2) {
if (s1 == s2)
return true;
if (s1 == null || s2 == null)
return false;
return s1.equals(s2);
}
@operator(differs)
public static boolean operatorDiffers(string s1, string s2) {
if (s1 == s2)
return false;
if (s1 == null || s2 == null)
return true;
return !s1.equals(s2);
}
}
[/code]
Deprecate String and Integer. Improve autoboxing so that you can use "int" anywhere you would currently be forced to use Integer. Add int.parse() etc. In short: Make it like C#. It would be backwards compatible.

sjasja
Offline
Joined: 2004-08-15
Points: 0

> In short: Make it like C#.

If you want a language like C# you know where to get it.

tackline
Offline
Joined: 2003-06-19
Points: 0

> Operator
> == should compare objects for equality, not identity.

I would agree that the 'identityEquals' operation is obscure enough not to have language support. However it does in Java, and there is no going back on that. Live with it.

> If you don't agree, give me one meaningful example
> where you would use operator == on two Integer
> objects.

Code, possibly performance critical, to compare two Integers, either of which may be null. In Integer.equals, one reference is of type Integer (this) and the other is of type Object.

Some types do not permit nulls. For instance, Hashtable and Queue (grrr). If you are queueing Integers and occassionally want a special value, then as special Integer object is a valid if hacky technique. The alternative is to confuse your code with another int wrapper class.

If you know your Integer objects will always be 'interned', then you can use == for a fast and uncluttered comparison. Swing uses this technique extensively with Booleans and Strings, although I wouldn't necessarily suggest it as a paragon of best practice.

podlesh
Offline
Joined: 2004-07-26
Points: 0

> jwenting, take a moment and think carefully about
discussion with jwentig is pointless, but I will try to respond to this

> Integer, String and object equality, ignoring how
> it's implemented in Java. Is it really correct that
> the equality operator applied to two Integer objects
> can return false even though they objects have the
> same value?
> Of course not, it's illogical.

Of course it is correct and logical. Operator == is defined as identity (object reference), not equality.

> Operator == should compare objects for equality, not identity.
Why?

We can have some new, special operator to compare equality (it would expand to .equals() call anyway). I don't see any problem with this - as long as this operator isn't something confusing (for example === , this would be very error-prone).
But you can't redefine one of the basic operators and violate one of the basic design principles. It would turn Java into different language.

> If you don't agree, give me one meaningful example
> where you would use operator == on two Integer
> objects.

This antipattern:
[pre]
public class IntegerFieldType implements FieldType {
protected static final Integer NO_VALUE = new Integer(0);
/**
* Returns null when not entered and some default should be used,
* special value when empty,
* parsed value otherwise.
*/
public Object parseValue(String valueString) throws InvalidInputValue {
if (valueString==null) return null;
if (valueString.trim().length()==0)
return NO_VALUE;
try {
return Integer.valueOf(valueString);
} catch (NumberFormatException e) {
throw new InvalidInputValue(valueString, e);
}
}

/**
* Test, if this value is empty (not present in data backend).
*/
public boolean isValueEmpty(Object value) {
//all integer values are valid
// null is used
return value==NO_VALUE;
}
}
[/pre]
Yes, it's bad design, but this is just an example I've made up right now. But code like this is actually used and it would [b]break[/b] if you redefine == to test equality.

mayhem
Offline
Joined: 2003-06-11
Points: 0

>> Operator == should compare objects for equality, not identity.
> Why?

Because operator == means equality for all primitive types in Java. So, basicly you have different meaning for the same operator depending on the type of the arguments. Just look at the problems that occur with the introduction of autoboxing in Java.

> But you can't redefine one of the basic operators and violate one of the basic design principles. It would turn Java into different language.

Yep. I'm not saying the semantics of operator == should be changed in Java, it would break existing code, but IMHO it was a mistake to define it as object identity comparison, it should call equals() instead. This is one place where C# is better designed (there are other areas where C# is better too).

podlesh
Offline
Joined: 2004-07-26
Points: 0

> >> Operator == should compare objects for equality,
> not identity.
> > Why?
>
> Because operator == means equality for all primitive
> types in Java. So, basicly you have different meaning
> for the same operator depending on the type of the
> arguments.
1) I've written already: String is not primitive!
2) == means [b]always[/b] identity. For primitive types, identity is the same as equality.
3) If you feel that this is broken, it's very strange to solve it by breaking it even more.

It's true that primitive types in Java breaks "pure OOP". That's Java - if you don't like it, use Smalltalk or CLOS.

> Just look at the problems that occur with
> the introduction of autoboxing in Java.
Yes, autoboxing (or tather autounboxing) was very bad idea.

> > But you can't redefine one of the basic operators
> > and violate one of the basic design principles. It
> > would turn Java into different language.
>
> Yep. I'm not saying the semantics of operator ==
> should be changed in Java, it would break existing
> code, but IMHO it was a mistake to define it as
> object identity comparison, it should call equals()
> instead. This is one place where C# is better
> designed (there are other areas where C# is better
> too).
I absolutely disagree. I think that this is place where Java is better designed.

Of course, this is just a matter of personal opinion, experiences and taste. Java and C# are very similar, but the target audience is a little different.

mayhem
Offline
Joined: 2003-06-11
Points: 0

> 1) I've written already: String is not primitive!

I've never written that String is a primitive type or that it should be primitive.

> It's true that primitive types in Java breaks "pure
> OOP". That's Java - if you don't like it, use
> Smalltalk or CLOS.

Pure OOP would be nice, but value types with autoboxing comes pretty close.

> > Just look at the problems that occur with
> > the introduction of autoboxing in Java.
> Yes, autoboxing (or tather autounboxing) was very bad
> idea.

Autoboxing works better in C#.

> I absolutely disagree. I think that this is place
> where Java is better designed.
>
> Of course, this is just a matter of personal opinion,
> experiences and taste. Java and C# are very similar,
> but the target audience is a little different.

I'm a bit curious why you feel the need to compare object identities of immutable types (your example above is not a useful one). If two objects are equal it means they can replace each other, they can even be the same object in the JVM. It doesn't matter as long as you can compare them using an equality operator. For mutable types object equality and identity is the same.

fuerte
Offline
Joined: 2004-11-22
Points: 0

> > 1) I've written already: String is not primitive!
>
> I've never written that String is a primitive type or
> that it should be primitive.

In fact it can be thought that String is as much primitive as Integer and int. They all are immutable, and the language has built-in operators (operator overloading) for these. String supports + and Integer supports > < >= <= but they do not support ==, which is a problem. And I would like plain "int" to behave like object, so that I could write int.parse() instead of Integer.parseInt().

> > It's true that primitive types in Java breaks
> "pure
> > OOP". That's Java - if you don't like it, use
> > Smalltalk or CLOS.
>
> Pure OOP would be nice, but value types with
> autoboxing comes pretty close.
>
> > > Just look at the problems that occur with
> > > the introduction of autoboxing in Java.
> > Yes, autoboxing (or tather autounboxing) was very
> bad
> > idea.
>
> Autoboxing works better in C#.

Correct. Java is broken as it is now.

> > I absolutely disagree. I think that this is place
> > where Java is better designed.
> >
> > Of course, this is just a matter of personal
> opinion,
> > experiences and taste. Java and C# are very
> similar,
> > but the target audience is a little different.
>
> I'm a bit curious why you feel the need to compare
> object identities of immutable types (your example
> above is not a useful one). If two objects are equal
> it means they can replace each other, they can even
> be the same object in the JVM. It doesn't matter as
> long as you can compare them using an equality
> operator. For mutable types object equality and
> identity is the same.

== is a natural syntax for comparing primitive and primitive-like object values. If Java had operator-overloading, this problem could be fixed.

podlesh
Offline
Joined: 2004-07-26
Points: 0

> Yep, C# has got it right, Java has got it wrong.
> String, Integer etc. in Java ARE immutable value
> types, but are not treated as such in the language.

Java got it right.
String and Integer are [b]immutable[/b], but they are not [b]primitive[/b]. String is typical composed object.

If God wanted String to be primitive, he wouldn't let us invent alphabet.
(I apologize for my english).

This discussion started with proposal to make String primitive. Some languages have some concept of primitive String (Lisp atoms). Java actually have tool to achieve this: method String.intern().

> Using object identity for comparing immutable objects
> is meaningless and is only a source of more
> programming errors.

There is no such concept of special, immutable objects in java.

jwenting
Offline
Joined: 2003-12-02
Points: 0

> It's simple. == compares the reference with all
> objects, except string. == compares the value with
> all primitives and primitive like objects like
> string. I wish that Java would behave the same.

Which would immediately break the language in that you'd never know what the heck == does.
== compares references, ALWAYS. If you can't rely on that, you can't do any comparisons anymore.

And there you immediately hit on a major problem with operator overloading as well, it makes it impossible to rely on operators to have predictable behaviour.

mayhem
Offline
Joined: 2003-06-11
Points: 0

jwenting, take a moment and think carefully about Integer, String and object equality, ignoring how it's implemented in Java. Is it really correct that the equality operator applied to two Integer objects can return false even though they objects have the same value? Of course not, it's illogical. Operator == should compare objects for equality, not identity. If you don't agree, give me one meaningful example where you would use operator == on two Integer objects.

mthornton
Offline
Joined: 2003-06-10
Points: 0

> jwenting, take a moment and think carefully about
> Integer, String and object equality, ignoring how
> it's implemented in Java. Is it really correct that
> the equality operator applied to two Integer objects
There is a significant difference between Integer and String in this respect. Suppose we have a million character String s, then let s1=s.substring(0, 10), and s2 = new String(s1). Now s1 and s2 have equal value, but s1 will reference 2 million bytes of heap whereas s2 only references approximately 20 bytes of heap (ignoring various overheads). Thus these objects have the same value but very different consequences.

sjasja
Offline
Joined: 2004-08-15
Points: 0

>>> Point is, that currently == can't be used with built-in
>>> types, because it is too unpredictable:
>>
>> It can be used! I use it daily with great success.
>
> Please post a sample of your daily code where you use
> == with Integers or Strings or other built-in types.

I don't often use == with those particular types (except for comparison against null). Sometimes with interned Strings but that's rare. I do use it with great success with other types though. I guess some of those types can be called "built-in" - they are as "built-in" as String or Integer.

I know the difference between == and equals(). I also know the difference between +, -, *, /, for(), if(), ... Pick the right one for the task at hand. == works extremely predictably for object identity comparision - that's what it is for, that's what it does.

sjasja
Offline
Joined: 2004-08-15
Points: 0

> Generics : Not in C# until 2.0
> Enhanced for Loop : Copied from C# (a different syntax though)
> Autoboxing/Unboxing: Copied from C# (partly)
> Typesafe Enums: Copied from C#
> Varargs : Not in C#
> Static Import : dunno
> Metadata (Annotations) : Copied from C# (different syntax)

I don't think C# is the originator of any of those features. It would be more correct to say "copied from LISP", "copied from Smalltalk", etc for most of those...

> Point is, that currently == can't be used with built-in
> types, because it is too unpredictable:

It can be used! I use it daily with great success. You just need to understand what == does for objects: it compares object identity. It does this at great predictability. Making == do something else occasionally would reduce from, not add to its predictability.

"== can't be used" is like saying "* can't be used because it doesn't perform division". That's...not...what...it...does...dude...seriously...

fuerte
Offline
Joined: 2004-11-22
Points: 0

> > Point is, that currently == can't be used with
> built-in
> > types, because it is too unpredictable:
>
> It can be used! I use it daily with great success.

Please post a sample of your daily code where you use == with Integers or Strings or other built-in types.

subanark
Offline
Joined: 2004-11-26
Points: 0

E.g. 1:
/**
* When a component in our dialog has this user property
* defined, the OK button will grayed out, and the tooltip
* for the OK button will include a description of what data
* is invalid. We create a new String to avoid any possible
* collision with other properties that may be set.
*/
public static final String INVALID_DATA = new String("INVALID_DATA");

E.g. 2:
/**
* Our table lock. We use a String for debugging help.
*/
private final String LOCK = new String(OurClass.class.getName()+" LOCK");

fuerte
Offline
Joined: 2004-11-22
Points: 0

I can understand 1) but it could be rewritten by adding a separate boolean property if the data is valid or not.

Or, there could be a cast to object. Compiler could detect all String comparisons with == and give a warning... it would be so simple.

podlesh
Offline
Joined: 2004-07-26
Points: 0

> I can understand 1) but it could be rewritten by
> adding a separate boolean property if the data is
> valid or not.
So, do you seen now that your proposal [b]does[/b] break old code?

> Or, there could be a cast to object. Compiler could
> detect all String comparisons with == and give a
> warning... it would be so simple.
No, it wouldn't be simple at all. It would be ugly, complicated, very error-prone mess. Just like the problems with autoboxing, which you don't like.

((String)s1) == ((String)s2)
must be the same code as
((Object)s1) == ((Object)s2)

If you break this rule (autoboxing did than!), it will cause confusing and non-obvious bug.

fuerte
Offline
Joined: 2004-11-22
Points: 0

> > I can understand 1) but it could be rewritten by
> > adding a separate boolean property if the data is
> > valid or not.
> So, do you seen now that your proposal [b]does[/b]
> break old code?

Yes, in rare cases.

> > Or, there could be a cast to object. Compiler
> could
> > detect all String comparisons with == and give a
> > warning... it would be so simple.
> No, it wouldn't be simple at all. It would be ugly,
> complicated, very error-prone mess. Just like the
> problems with autoboxing, which you don't like.

It would be simple. If you get a warning, just add cast to Object.

> ((String)s1) == ((String)s2)
> must be the same code as
> ((Object)s1) == ((Object)s2)
>
> If you break this rule (autoboxing did than!), it
> will cause confusing and non-obvious bug.

Perhaps the next version should not change == but add that warning always. That way the code would be updated to add explicit cast to Object, and in the next version (7.0) the change could be done.

fred33
Offline
Joined: 2005-08-16
Points: 0

> > > I can understand 1) but it could be rewritten by
> > > adding a separate boolean property if the data
> is
> > > valid or not.
> > So, do you seen now that your proposal [b]does[/b]
> > break old code?
>
> Yes, in rare cases.
>
If it can break code in the generalized case, then this is enough to prevent it being changed.

fuerte
Offline
Joined: 2004-11-22
Points: 0

> > > > I can understand 1) but it could be rewritten
> by
> > > > adding a separate boolean property if the data
> > is
> > > > valid or not.
> > > So, do you seen now that your proposal
> [b]does[/b]
> > > break old code?
> >
> > Yes, in rare cases.
> >
> If it can break code in the generalized case, then
> this is enough to prevent it being changed.

Still there is no actual proof that the code would stop working. == would still compare the object reference first, and only if it doesn't match, then the value. In that case the value is "INVALID_DATA", and it is very unlikely, that the actual, valid data, would contain that value. We would need to see more of that code.

Message was edited by: fuerte

subanark
Offline
Joined: 2004-11-26
Points: 0

Lets say I have a component that is checking validation on input. I have a general component class lets call it SelectName. Let us say that select name sets the component property "INVALID_DATA" to true when it contains no text, and removes the property when there is text. This component is placed in a component I will call EnablableComponent that contains a checkbox that will enable or disable its children, in addition it will use its parent's key "INVALID_DATA" to say its invalid if its children are invalid, but only if it is enabled. The main component will disable OK if any of its children have the property "INVALID_DATA" that it created. Thus if == was added to mean equals then it would diable its self if one of its deep components was invalid but disabled.

Even though this is somewhat complex, I am one of the very few people who post on this form, there are lots of people out there who do similar tricks that don't even know this form exists.

fuerte
Offline
Joined: 2004-11-22
Points: 0

Perhaps it would be best to do what the original author suggested, so add "string" type, but add operator overloading as well, so that we would have ==.

Of course, then the problem with Integers and other types would remain (>= and <= work but == does not).

So, there is no solution to this dilemma. I should accept Java as it is. Nothing is perfect.

What if we had C# compiler for Java runtime... C# is not perfect either, it does not have varargs.

subanark
Offline
Joined: 2004-11-26
Points: 0

The easy solution is to provide an annotation that programmers can use on their classes/methods to speficy that == means .equals or whatever operation you think is good, it can be argued if this will just add bloat/confusion into the language, but at least it will be backwards compadible.

There is a C# compiler for java runtime.
C# does have varargs just use the params keyword (instead of ...).

fuerte
Offline
Joined: 2004-11-22
Points: 0

> The easy solution is to provide an annotation that
> programmers can use on their classes/methods to
> speficy that == means .equals or whatever operation
> you think is good, it can be argued if this will just
> add bloat/confusion into the language, but at least
> it will be backwards compadible.

Yes, operator overloading is the answer. We could have java.lang.newtypes or something, which would have:

Integer => Int and Int32
Boolean => Bool
Character => Char
Long => Int64
Short => Int16
Byte => Int8
String => Str or string ???
Float => Float32
Double => Float64

> There is a C# compiler for java runtime.

Where?

> C# does have varargs just use the params keyword
> (instead of ...).

Oh yes, how did I miss that?

Message was edited by: fuerte

subanark
Offline
Joined: 2004-11-26
Points: 0

I think the JDK copied very few things from C#.

C#'s autoboxing is quite a bit different from java's autoboxing.
In java the autoboxing will convert
byte <-> Byte
char <-> Character
ect...

C# on the other had does not have explicit wrapper classes instead it boxes a value type (primative or struct) when you assign it to object. The problem with this is you cannot assign null to an int unless you assign it to an object first. C# 2.0 fixes this by allowing nullable types.

>=, <= did not work with Integer previously, that functionality is there since the statement would not be legal unless unboxing occured. == operates on Integers the way it always has.

Edit on previous post:
After looking at the c# language the == is an operator you can overload that equates to a static method, so string does specially handle ==, but programmers expect this to occur.

fuerte
Offline
Joined: 2004-11-22
Points: 0

You won't let me go!

New features in JDK 5.0:

Generics : Not in C# until 2.0
Enhanced for Loop : Copied from C# (a different syntax though)
Autoboxing/Unboxing: Copied from C# (partly)
Typesafe Enums: Copied from C#
Varargs : Not in C#
Static Import : dunno
Metadata (Annotations) : Copied from C# (different syntax)

About boxing in C#:

"
Boxing is an implicit conversion of a value type to the type object or to any interface type implemented by this value type. Boxing a value of a value allocates an object instance and copies the value into the new object.

Consider the following declaration of a value-type variable:

int i = 123;
The following statement implicitly applies the boxing operation on the variable i:

object o = i;
The result of this statement is creating an object o, on the stack, that references a value of the type int, on the heap. This value is a copy of the value-type value assigned to the variable i.
"

Also:

"
// You can modify the value of j by using
// the byref method with this signature.
public static void m1( ref int j ) {
j = Int32.MaxValue;
}
"

int i = 1;
m1(ref i);
// i = Int32.MaxValue;

podlesh
Offline
Joined: 2004-07-26
Points: 0

> You won't let me go!

We don't want you to go (except jwentig, just ignore him). We want you to refine your arguments.

Keep in mind that any changes you propose:
- must follow basic design concepts of Java language
- must not break old code (it doesn't matter that this old code is bad practice - just don't break it)

Autoboxing in 1.5 follows that and (in my opinion) it's bad and broken. It should never be introduced, because of the == vs. <= inconzistency (== applies on Integer objects and compares references; <= doesn't, causes unboxing and compares values).

> New features in JDK 5.0:
> Generics : Not in C# until 2.0
> Enhanced for Loop : Copied from C# (a different
> syntax though)
> Autoboxing/Unboxing: Copied from C# (partly)
> Typesafe Enums: Copied from C#
> Varargs : Not in C#
> Static Import : dunno
> Metadata (Annotations) : Copied from C# (different
> syntax)

I think that enums are quite different in C# (it has support in CLR). So, that's 4.5 of 7, exactly half :-)

> About boxing in C#:
1) C# has different virtual machine
2) C# has operator overloading

pholthuizen
Offline
Joined: 2005-02-12
Points: 0

> >
> > Simply cast to object:
> >
> > if ((object)s1 == (object)s1)
> >
> > Thanks for the support! :-)
>
> Erm... lets try to avoid stuff like that.

To me it doesn't seem the ultimate solution either, but at least it is better than having to use

(m != null && m.equals(n)) || (m == n)

all the time...

makeworld
Offline
Joined: 2005-08-21
Points: 0

>
> To me it doesn't seem the ultimate solution either,
> but at least it is better than having to use
>
> (m != null && m.equals(n)) || (m == n)
>
> all the time...

I'd be very scared to see what could get into this code block. If m and n are both null, this statement is true. If m's equal function is broken for the identity case (look in the javadoc's equals contract) then this statement is true. In this case... you probably shouldn't be using whatever object M is.

This whole thread really is a non-issue. The == has always meant very clearly referential equality while the .equals means value equality. If you need value equality on constants simply put the constant on the LEFT HAND SIDE of the statement - not the right hand side.

if ( "foo".equals( s ) )

And there you have it - s is non-null and definately equal to foo if this test passes. If you don't want to have magic strings hanging around in your code you can very simply do something like:

public class MyClass {

private static final String FOO = "foo";

public static void main ( Strings [] args ) {
/* ... */
if ( FOO.equals ( s ) ) {
System.out.println( "foo!" );
}
}
}

fuerte
Offline
Joined: 2004-11-22
Points: 0

> This whole thread really is a non-issue. The == has
> always meant very clearly referential equality while
> the .equals means value equality.

int a = 1;
int b = 2;
if (a == b) // referential equality or value equality?

> if ( "foo".equals( s ) )

if (s == "foo")

is still more beautiful and easier to write and read, and would not break anything.

jwenting
Offline
Joined: 2003-12-02
Points: 0

> if (s == "foo")
>
> is still more beautiful and easier to write and read,
> and would not break anything.

Sigh... It breaks EVERYTHING.
It breaks == as being a comparison between references instead of values if == is changed to do what you want it to do.
Or are you still going on about turning everything into primitives and doing away with objects altogether (in which case I refer you to Cobol or Fortran).

fuerte
Offline
Joined: 2004-11-22
Points: 0

> > if (s == "foo")
> >
> > is still more beautiful and easier to write and
> read,
> > and would not break anything.
>
> Sigh... It breaks EVERYTHING.

Okay, please post a code snipped of a working program which it would break. I don't think that you can find even one.

> It breaks == as being a comparison between references
> instead of values if == is changed to do what you
> want it to do.

== already compares the values when it is used with primitives. It does not compare object references with "int"s.

> Or are you still going on about turning everything
> into primitives and doing away with objects
> altogether (in which case I refer you to Cobol or
> Fortran).

C# has "string", where == compares the value instead of reference. C# "string" is object just like Java "String". C# designers made a very good choice... but then, they had Java which they could improve. If Java was desinged now, then == would compare the value with Strings.

subanark
Offline
Joined: 2004-11-26
Points: 0

String is not primative, String extends Object.

I will sometimes use the String copy constructor to get a new private reference to a String that will not colide with other people's String (and my own) if they use the same string. In this case I would need to cast to object in order to determine if they are reference equals. In this case I would need to change my code if this was implemented.

C#'s string does not implement == as equals. Its implemented that way in object, string just inherrits that language feature.

If I wanted to compare the reference of two strings (or any object) in C# I would:
bool refEquals = object.ReferenceEquals(s1,s2);

Any change that is made to the synatx of the language should either compile older code so it is functionality equivilient or give an error message to the user (this assumes the highest -source flag is used). Do not say "no one does it this way," because you will find people who do.

fuerte
Offline
Joined: 2004-11-22
Points: 0

> String is not primative, String extends Object.

Really?

> I will sometimes use the String copy constructor to
> get a new private reference to a String that will not
> colide with other people's String (and my own) if
> they use the same string. In this case I would need
> to cast to object in order to determine if they are
> reference equals. In this case I would need to change
> my code if this was implemented.

I don't understand your code. I can't imagine the real use.

> C#'s string does not implement == as equals. Its
> implemented that way in object, string just inherrits
> that language feature.

What. In C# strings == compares the value, not the reference.

> If I wanted to compare the reference of two strings
> (or any object) in C# I would:
> bool refEquals = object.ReferenceEquals(s1,s2);

You can also do

bool refEquals = (object)s1 == (object)s2

Shorter to write. Although casting is bad.

> Any change that is made to the synatx of the language
> should either compile older code so it is
> functionality equivilient or give an error message to
> the user (this assumes the highest -source flag is
> used). Do not say "no one does it this way," because
> you will find people who do.

There could be a compiler option (disabled by default) to give a warning about new == string comparison. That way old code could be easily checked for problems.

jwenting
Offline
Joined: 2003-12-02
Points: 0

> > String is not primative, String extends Object.
>
> Really?
>
Yup, something you seem to not have gotten into your head (where it seems there's more than enough empty space to fit it if you remove some of that hot air).

> > I will sometimes use the String copy constructor
> to
> > get a new private reference to a String that will
> not
> > colide with other people's String (and my own) if
> > they use the same string. In this case I would
> need
> > to cast to object in order to determine if they
> are
> > reference equals. In this case I would need to
> change
> > my code if this was implemented.
>
> I don't understand your code. I can't imagine the
> real use.
>
That's your problem, he quite clearly explained it.

> > C#'s string does not implement == as equals. Its
> > implemented that way in object, string just
> inherrits
> > that language feature.
>
> What. In C# strings == compares the value, not the
> reference.
>
yes, because in C# == is probably defined (using operator overloading) to just call the equivalent of the equals method.
That's NOT how things should work and indeed not how they work in Java, something you don't seem to grasp.

> > Any change that is made to the synatx of the
> language
> > should either compile older code so it is
> > functionality equivilient or give an error message
> to
> > the user (this assumes the highest -source flag is
> > used). Do not say "no one does it this way,"
> because
> > you will find people who do.
>
> There could be a compiler option (disabled by
> default) to give a warning about new == string
> comparison. That way old code could be easily checked
> for problems.

No, there should be no special treatment of == for Strings (or anything else) at all.
Instead you should get it into your head how Strings work and use them properly instead of trying to bully the entire community into accepting your deranged ideas of how the world should work.

fuerte
Offline
Joined: 2004-11-22
Points: 0

Okay, I rest my case, I surrender... :-)

(Last comment: Why did JDK 5.0 copy most of the new features from C#? Why Java has now auto-boxing? To make programming easier? Why >= and <= work with Integers but == does not? Why there is no such problems in C#? Why C# strings compare values with == but Java Strings do not?)

podlesh
Offline
Joined: 2004-07-26
Points: 0

> Why did JDK 5.0 copy most of the new features from C#?
Most???

> Why Java has now auto-boxing? To make programming easier?

Yes, experience with the autoboxing (and its problems with operators) is very good reason [b]against[/b] your proposal.

> Why >= and <= work with
> Integers but == does not? Why there is no such
> problems in C#? Why C# strings compare values with ==
> but Java Strings do not?

Read the documentation, please. When you learn Java language and its principles, answers will to these questions will be obvious.

Of course, you can have your opinion about Java language design. But it's impossible to change basic concepts [b]now[/b], after ten years. And many people think that they are good and should't be changed at all.

jwenting
Offline
Joined: 2003-12-02
Points: 0

> > A beautiful language is one with clearly defined
> > semantics where things have one purposem, I just
> > can't see how that is going to happen if ==
> suddenly
> > starts taking a new meaning. This is precisely the
> > reason I despise this:
> >
> > Integer a=5;
>
> But == already compares the value with primitives. It
> already has two meanings. The suggestion with
> Integers and Strings is that == would compare the
> value only if the object references are different. It
> just would make the life easier, and the syntax
> simpler. Think about the following:
>
WRONG, completely and utterly WRONG!
When used with Objects (which Strings are, unlike what you seem to think) == DOES compare values.
It compares the values of the references you are comparing.

In your 'ideal' world there would be no telling what is being compared when you use ==. Is it comparing the references, executing the equals method, or doing something else entirely?

> if (s != null && s.equals("test"))
>
> How many times have you seen that? Why not write it
> simply:
>
> if (s == "test)

Write it if you like, just don't come crying when it doesn't do what you think it should.

pholthuizen
Offline
Joined: 2005-02-12
Points: 0

> It's not that. I have programmed with most of those
> languages with no difficulties, but I just wanted to
> make Java syntax better, more beautiful.
>
> Also, == would not mean .equals(). It would mean:
>
> 1) return true if both object references are equal
> (non-null or null)
>
> 2) return false if either one is null
>
> 3) only then compare values, and return true if
> values are equal
>
> See the difference? == would work with null strings,
> there would be no null exceptions ever.

I can't see anything wrong with this proposal, I think it is a good idea. The only problem with it might be that:
1. The interpretation of the == operator becomes very complex.
2. You loose the operator which tests for reference equality only which is still needed, maybe an additional operator might do the trick.

I can't imagine that Sun didn't think of this yet, there must be other reasons why it is not in the language.

fuerte
Offline
Joined: 2004-11-22
Points: 0

> 2. You loose the operator which tests for reference
> equality only which is still needed, maybe an
> additional operator might do the trick.

Simply cast to object:

if ((object)s1 == (object)s1)

Thanks for the support! :-)

subanark
Offline
Joined: 2004-11-26
Points: 0

>
> Simply cast to object:
>
> if ((object)s1 == (object)s1)
>
> Thanks for the support! :-)

Erm... lets try to avoid stuff like that.

fuerte
Offline
Joined: 2004-11-22
Points: 0

> > Simply cast to object:
> >
> > if ((object)s1 == (object)s1)
> >
> > Thanks for the support! :-)
>
> Erm... lets try to avoid stuff like that.

Yes, normally you would never have to do it.

sbohmann
Offline
Joined: 2005-09-22
Points: 0

I've always found it the worst of features of C# that I can never be certain whether operator == will compare by reference or value.

This forces me to use

if ((Object)a == (Object)b) ...

on instances of a class I haven't used before or whenever I simply don't remember whether the class had implemented operator ==, or not.

It is NEVER about brevity. It is NEVER about beauty.

It is always only about clarity. Hitting some more keys on the keyboard doesn't hurt nearly as much as ALWAYS having to think about every single tiny detail, just because there are no consistent mechanics to understand, but merely a lot of possible different ways a type might have been implemented in order to manipüulate the language's basic syntax.

Whenever one has to write code for .NET, I strongly recommend using J#.NET, as the absence of overloaded operators, or at least of the possibility to use them as operators, in contrary to calling, say, operator_Equals(,), gave me the feeling to be able to breathe again.

With all that unnecessary balance, it was like every single type i used was constantly talking to me and telling me about all the great new concepts and features and own ideas about syntax and semantics it offered, like in a giant, bloody, headache causing, eternal commercial spot.

And besides, all that J#.Net gives me, compared to Java, is having to start thinking about things I don't care about, just not as much as in C#, as well as "Windows Forms".

I have myself often complained about the absence of unsigned types, but to be honest, this is a tiny price to pay.

Java is a great tool, and I'm capable of entirely understanding it, and after having understood some basics, like the difference between string literals and new strings, or why all these types are immutable and how to manipulate strings the right way, I can simply use this language, and the only features of libraries I use I have to think about are the methods of their public interfaces.

The operators, I understand already. And I appreciate it very much that I haven't got to learn their use again ans again for each new class I encounter.

All of this said, I am NOT in favour of "string primitives that implement == via .equals()".

I strongly oppose them.

That kind of C# stuff makes life easier for people who've had Basic at School.

But it makes every day's work a lot harder for programmers.

fuerte
Offline
Joined: 2004-11-22
Points: 0

It's simple. == compares the reference with all objects, except string. == compares the value with all primitives and primitive like objects like string. I wish that Java would behave the same.

darcy
Offline
Joined: 2003-06-15
Points: 0

Easy way to solve it :-)

String s = new String("hello");
String t = new String("hello");
Object os = s;
Object ot = t;

if(s == t) System.out.println("equal");
if(os == ot) System.out.println("equal");

If both of those print out "equal" then you have a screwed up thing where Objects that are really Strings behave differnetly than other objects.

If only the String one prints out "equal" then you have a screwed up thing where the "same" objects are not == to one another.

This matters for cases where .equals and == will report different values for Strings based on how the variables are declared - that is just asking for trouble.

The semantics for = are really the same for everything in Java as it is now... if you think a bit differently:

All primitives are really singletons... thus they are all have references (rather than just a value). Then == always compares references (physical memory location) regardless of if it is a primitive or an object :-)

mayhem
Offline
Joined: 2003-06-11
Points: 0

Yep, C# has got it right, Java has got it wrong. String, Integer etc. in Java ARE immutable value types, but are not treated as such in the language. Using object identity for comparing immutable objects is meaningless and is only a source of more programming errors. That's why autoboxing has those nasty pitfalls in Java, but in C# they can be avoided.

jwenting
Offline
Joined: 2003-12-02
Points: 0

They ARE treated as such. Java got it quite right, it's your head that got it wrong.
These types are Object types, NOT primitive types.
And they are treated exactly like all other Object types.
If they were primitives they wouldn't be intrinsically immutable.

If you like C# so much better, why don't you stop bothering us and go bask in its light?

nullpointer
Offline
Joined: 2005-04-10
Points: 0

Well, from other point of view, it is very strange that Sun added a concatenation operator "+" for String type and didn't add a comparence operators. You are right that in 99% of cases people use string values and not references. Perhaps it is a good idea that a language has a sting as primitive type like many other languages do. With autoboxing implementation of string type will not have any problem (except that we add new primitive type).