0

I am looking to see in the Java source code what happens when a variable is declared & assigned a value.

I haven't been able to spot this in java.lang.Class.

Particularly, looking to see what happens in

String s1 = "abc";
String s2 = "abc";

String is immutable and thus by the outcome of "s1 == s2", these two references-- s1 and s2 are pointing to the same object and when

String s2 = "abc";

is issued, Java is spotting the location of the object "abc" that already is created and s1 is referring to, and assigning this location to s2 (?)

I am looking to see how this is handled behind the scenes in Java.

//===========================================

EDIT:

The Q here is-- how Java is handling this in its source code.

The What is the Java string pool and how is "s" different from new String("s")? is answering this in part. I'm looking to see this all in the source code-- if it's not one of those native.

I know this a naive Q, but didn't expect these responses.

Community
  • 1
  • 1
Roam
  • 4,831
  • 9
  • 43
  • 72
  • 4
    A `String` being immutable has *nothing* to do with the internal String pool java uses for string literals. – Brian Roach Aug 02 '13 at 20:31
  • If `String`s weren't immutable, they couldn't be interned. – chrylis -cautiouslyoptimistic- Aug 02 '13 at 20:38
  • @chrylis Yes but just because something *is* immutable doesn't mean it's interned. Java could have had an immutable String without interning. In fact, that's exactly what you get with `new String()` – Brian Roach Aug 02 '13 at 20:40
  • Sure they could. It would be a terrible idea, because it would lead to hard-to-track bugs (and security holes); but it'd be perfectly possible to have a rule of "two string constants of the same string will always return the same mutable `String` object." – yshavit Aug 02 '13 at 20:40
  • @BrianRoach Oh, absolutely you could, but it's the fact that `String`s are immutable that make interning possible... er (@yshavit), practical. – chrylis -cautiouslyoptimistic- Aug 02 '13 at 20:41
  • (In fact, if you don't have a security manager that prevents reflection-based modifcation, `Strings` [aren't even immutable](https://gist.github.com/yshavit/6143346).) – yshavit Aug 02 '13 at 20:48
  • @Roam, re `if it's not one of those native` -- the String interning is done by the JVM during class loading, so yes, it's native. The closest you'll see of it is in the source is the declaration for `java.lang.String.intern()`, but that's just a native function (at least in openjdk): http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/lang/String.java#String.intern%28%29 – yshavit Aug 02 '13 at 20:54
  • @yshavit I was looking to see which constructor of String / how invoked upon an assignment that would/not involve pooling. that's "how the compiler is behaving"-- before handing it over to String. or handing it over right away upon on assignment of a Class type value and leaving the rest to String-in-this-case. Havent had a thorough look but nothing showing in java.lang.Class. – Roam Aug 02 '13 at 20:58
  • @Roam you are better off using `javap` if you want a look at the bytecode for a class to get an idea of how string literals/constants work. I think my answer addresses you concern. – Tim Bender Aug 02 '13 at 21:11

3 Answers3

0

That depends on the JVM. Implementations may vary.

Michael
  • 3,935
  • 4
  • 24
  • 25
0

One mental model:

  1. At compile time, all String literals are written into the bytecode of the class definition in a "constants table". String instances in particular will be stored into the interned string pool (during loading?).
  2. At runtime, when a string literal is to be referenced, it is retrieved with a ldc load from the constants table which is an interned string object.

In your example...

String s1 = "abc";
String s2 = "abc";

May become something like:

String s1 = ldc #1
String s2 = ldc #1

Where:

constant #1 = "abc".intern();

I haven't been able to spot this in java.lang.Class.

I'm not sure why you would be looking at java.lang.Class, if anywhere, I would be looking at the ClassLoader, however even class loading is native. If you want to see some sort of "code", you can examine the bytecode of a compiled class with javap. There is an old guide that somewhat explains reading bytecode instructions. You'll notice that all references to String literals are ldc instructions which is for loading constants.

Tim Bender
  • 20,112
  • 2
  • 49
  • 58
0

I'm looking to see this all in the source code-- if it's not one of those native.

It's about as native as a thing can get -- it's handled by the JVM, which has a bytecode operation for "load this string literal".

Take this code:

public class StringLiterals {
  public static void main(String[] args) {
    String s = "hello, world";
  }
}

If you compile that and then run javap -c StringLiterals, you'll get this:

Compiled from "StringLiterals.java"
public class StringLiterals extends java.lang.Object{
public StringLiterals();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   ldc #2; //String hello, world
   2:   astore_1
   3:   return

}

The second code 0 and 1 are what correspond to String s = "hello, world"; the code 0 corresponds to the string literal "hello, world". It says to load const #2 in the .class file, and hints that it's the string literal hello, world. If you run javap -c -verbose StringLiterals you'll see all of the consts defined in the .class file, and it'll confirm that the second one is that string literal:

Compiled from "StringLiterals.java"
public class StringLiterals extends java.lang.Object
  SourceFile: "StringLiterals.java"
  minor version: 0
  major version: 50
  Constant pool:
const #1 = Method   #4.#13; //  java/lang/Object."<init>":()V
const #2 = String   #14;    //  hello, world
const #3 = class    #15;    //  StringLiterals
...

The JVM is free to handle this however it wants, but openjdk does it natively, so you won't see any of the relevant code in the Java source.

yshavit
  • 42,327
  • 7
  • 87
  • 124