Identical string literals in a java source file are all references to one String. So in my class if I have two occurrences of "foo", then they are equals (in the == sense).
The moment you call new String("foo") you create a new String object.
eg.
[michael@mira stringtest]$ javac StringOne.java
[michael@mira stringtest]$ cat StringOne.java
public class StringOne {
public static void main(String[] args) {
System.out.println("foo" == "foo");
System.out.println("foo" == new String("foo"));
System.out.println("foo" == new String("foo").intern());
}
}
[michael@mira stringtest]$ javac StringOne.java
[michael@mira stringtest]$ java StringOne
true
false
true
intern() returns a reference to a String in the shared pool. In this case it's the one which loaded with the class.
And just in case you don't believe me, look at the bytecode generated by this little class:
[michael@mira stringtest]$ cat StringTwo.java
public class StringTwo {
public String sane() {
return "foo";
}
public String insane() {
return new String("foo");
}
}
[michael@mira stringtest]$ javap -c StringTwo
Compiled from "StringTwo.java"
public class StringTwo extends java.lang.Object{
public StringTwo()
Code:
0: aload_0
1: invokespecial #1;//Method java/lang/Object."":()V
4: return
public java.lang.String sane();
Code:
0: ldc #2;//String foo
2: areturn
public java.lang.String insane();
Code:
0: new #3;//class String
3: dup
4: ldc #2;//String foo
6: invokespecial #4;//Method java/lang/String."":(Ljava/lang/String;)V
9: areturn
}
[michael@mira stringtest]$
The compiler cannot make the optimisation you refer to because you have explicitly asked it for two different Strings and so the optimisation would not preserve the semantics of your code.
So, in summary, don't ever write new String("foo"), new String(String string) has one good use, and that's to minimise the size of the backing char[]. This can become vastly over sized because StringBuffer.toString() will share arrays until another modification is made to the StringBuffer (for performance reasons), but if your StringBuffer was big and is now small...
We had a small amount of pain going from 7.1 to 8, the problem was to do with invalid unicode characters, I thought the databases were created with encoding UNICODE on both versions, but it was a while back and they might have been SQLASCII or something...
The problem was definitely with the data, and it was trivially solved with iconv...
Are you suggesting mapping a Web Application's users to OS users ?
No, I'm merely suggesting that if your app server doesn't do it, it is rubbish. Even if it does it may still be rubbish. *cough* websphere *cough*:)
Well may be for a intranet application within the company, but surely not for an internet application.
Sadly I just do intranet applications now, being able to integrate with a clients infrastructure with no work is great, excellent ticky box.
I'm not sure your problems are with JAAS, sounds more like they're with the servlet security gumpth.
Having said that, we get around your problems with j_security_check by hiding all calls to j_security_check behind a servlet which passes on some requests to j_security_check [1]. It's a bit of a hack but works. There are three real reasons to prefer this over writing your own user stuff:
Deployer can set the users up the way they're used to (and so can make it talk to ldap, a database, a flat file, local OS users, etc)
Your users are propogated to EJB land auto-magically
You can take advantage of the declarative security within your web app
When I used to write internet apps these reasons were considerably less compelling (where the users lived was always well known - declarative security doesn't give you quite enough control - and well, ejb's, they smell really!)
[1] Doing this generally, cross app-servers, is a bit of a pain.
This already handles authentication against unix logins, or windows logins, or pretty much anything else!
The article finishes with:
A pure Java implementation of MD5 crypt can provide a simple interface that can be used by Web applications to authenticate against the local UNIX registry.
I have two things to say:
1. If your app server doesn't support authentication against local OS users (and this is what you want) get a new one. 2. It is big and clever to write your own authentication system for web apps in 2006.
The OOP approach isn't limited to the class based languages. Class based languages have traditionally been more popular. The only recent mainstream prototype based language I can think of is javascript.
Saying one is better than the other is only ever likely to generate an argument, they're just different.
Have a look
here for the classic paper on the prototype based approach.
Refactoring is meant to be about improving the design of existing code, in small controlled ways. This doesn't look like refactoring, just a rewrite of a section of it.
Either way I find it hard to appreciate why this is news.
> That's one of the things I like about programming
> in Java: private members are truly private, and
> it's physically impossible for other code to
> access them, except as I expose them.
What you mean you can't do this?
// Make it accessible
privateField = String.class.getDeclaredField("value");
privateField.setAccessible(true);
String foo = new String("foo");
// Read it
Object oldValue = privateField.get(foo);
// Change it
privateField.setValue(foo, new char[] {'b', 'a', 'r'});
(to non java peeps, this will make the private field in the String class accessible, read it, and then change it via reflection)
I do agree whole heartedly with the point you're making though!:)
Sun MicroSystems and now Oracle develops JVMs for all the OSs EXCEPT Apple.
$ java -version
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build pap32devifx-20090327 (SR9-SSU ))
IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 AIX ppc-32 j9vmap3223-20081129 (JIT enabled)
J9VM - 20081126_26240_bHdSMr
JIT - 20081112_1511ifx1_r8
GC - 200811_07)
JCL - 20090327
Thanks for the link, hadn't realised they'd changed the behaviour in 5. Probably for the best as I've seen loads of memory leaks caused because of it!
One day I hope to get to use Java 5 at work, but still, at least I'm not still using 1.3!
Identical string literals in a java source file are all references to one String. So in my class if I have two occurrences of "foo", then they are equals (in the == sense).
The moment you call new String("foo") you create a new String object.
eg.
[michael@mira stringtest]$ javac StringOne.java[michael@mira stringtest]$ cat StringOne.java
public class StringOne {
public static void main(String[] args) {
System.out.println("foo" == "foo");
System.out.println("foo" == new String("foo"));
System.out.println("foo" == new String("foo").intern());
}
}
[michael@mira stringtest]$ javac StringOne.java
[michael@mira stringtest]$ java StringOne
true
false
true
intern() returns a reference to a String in the shared pool. In this case it's the one which loaded with the class.
And just in case you don't believe me, look at the bytecode generated by this little class:
[michael@mira stringtest]$ cat StringTwo.javapublic class StringTwo {
public String sane() {
return "foo";
}
public String insane() {
return new String("foo");
}
}
[michael@mira stringtest]$ javap -c StringTwo
Compiled from "StringTwo.java"
public class StringTwo extends java.lang.Object{
public StringTwo()
Code:
0: aload_0
1: invokespecial #1;
4: return
public java.lang.String sane();
Code:
0: ldc #2;
2: areturn
public java.lang.String insane();
Code:
0: new #3;
3: dup
4: ldc #2;
6: invokespecial #4;
9: areturn
}
[michael@mira stringtest]$
The compiler cannot make the optimisation you refer to because you have explicitly asked it for two different Strings and so the optimisation would not preserve the semantics of your code.
So, in summary, don't ever write new String("foo"), new String(String string) has one good use, and that's to minimise the size of the backing char[]. This can become vastly over sized because StringBuffer.toString() will share arrays until another modification is made to the StringBuffer (for performance reasons), but if your StringBuffer was big and is now small...
We had a small amount of pain going from 7.1 to 8, the problem was to do with invalid unicode characters, I thought the databases were created with encoding UNICODE on both versions, but it was a while back and they might have been SQLASCII or something...
The problem was definitely with the data, and it was trivially solved with iconv...
Any recent install of java will almost certainly have an xslt processor on it, you just have to remember the magic incantation:
java org.apache.xalan.xslt.Process -XSL [template] -IN [file]Are you suggesting mapping a Web Application's users to OS users ?
No, I'm merely suggesting that if your app server doesn't do it, it is rubbish. Even if it does it may still be rubbish. *cough* websphere *cough* :)
Well may be for a intranet application within the company, but surely not for an internet application.
Sadly I just do intranet applications now, being able to integrate with a clients infrastructure with no work is great, excellent ticky box.
I'm not sure your problems are with JAAS, sounds more like they're with the servlet security gumpth.
Having said that, we get around your problems with j_security_check by hiding all calls to j_security_check behind a servlet which passes on some requests to j_security_check [1]. It's a bit of a hack but works. There are three real reasons to prefer this over writing your own user stuff:
When I used to write internet apps these reasons were considerably less compelling (where the users lived was always well known - declarative security doesn't give you quite enough control - and well, ejb's, they smell really!)
[1] Doing this generally, cross app-servers, is a bit of a pain.
I don't understand why I would do this rather than just use JAAS (which has been part of the jdk since 1.4).
http://java.sun.com/products/jaas/
This already handles authentication against unix logins, or windows logins, or pretty much anything else!
The article finishes with:
A pure Java implementation of MD5 crypt can provide a simple interface that can be used by Web applications to authenticate against the local UNIX registry.
I have two things to say:
1. If your app server doesn't support authentication against local OS users (and this is what you want) get a new one.
2. It is big and clever to write your own authentication system for web apps in 2006.
implementing classes, the OOP approach
The OOP approach isn't limited to the class based languages. Class based languages have traditionally been more popular. The only recent mainstream prototype based language I can think of is javascript.
Saying one is better than the other is only ever likely to generate an argument, they're just different.
Have a look here for the classic paper on the prototype based approach.
Does it run linux?
:)
Imagine a beowulf cluster of those...
2001: A Space Odyssey came out in 1968 if memory serves, isn't Clarke getting a bit old?
I think he's nearly 90 now...
BBEdit has rectangular selection - I would hate to imagine how you would implement that in a non-GUI editor
What? You mean like ctrl-v in vi? :)
There is a way to do it in a tty in (x)emacs but I can't remember what it is, in x with xemacs it's just meta and the left button.
Does anyone know if it's possible to do a rectangular selection in eclipse?
Refactoring is meant to be about improving the design of existing code, in small controlled ways. This doesn't look like refactoring, just a rewrite of a section of it.
Either way I find it hard to appreciate why this is news.
> That's one of the things I like about programming
// Make it accessible
// Read it
// Change it
:)
> in Java: private members are truly private, and
> it's physically impossible for other code to
> access them, except as I expose them.
What you mean you can't do this?
privateField = String.class.getDeclaredField("value");
privateField.setAccessible(true);
String foo = new String("foo");
Object oldValue = privateField.get(foo);
privateField.setValue(foo, new char[] {'b', 'a', 'r'});
(to non java peeps, this will make the private field in the String class accessible, read it, and then change it via reflection)
I do agree whole heartedly with the point you're making though!