Difference between revisions of "Programming in D for Java Programmers"
m (O3o moved page Coming From/Java to Programming in D for Java Programmers) |
(Difference between Java's static member variables and D's) |
||
Line 13: | Line 13: | ||
}</syntaxhighlight> | }</syntaxhighlight> | ||
+ | == Static Class Member Variables == | ||
+ | |||
+ | In Java if you declare a member variable as <code>static</code> it will be stored in global storage for the entire program, allowing you to access the same reference from multiple threads. | ||
+ | |||
+ | <syntaxhighlight lang="Java"> | ||
+ | class Person { | ||
+ | public String firstName; | ||
+ | |||
+ | public Person(String fname) { | ||
+ | this.firstName = fname; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class ProgramState { | ||
+ | public static Person person; | ||
+ | |||
+ | static { | ||
+ | person = new Person("Jessie"); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public class Program { | ||
+ | |||
+ | public static void main(String[] args) throws Exception { | ||
+ | new ProgramState(); | ||
+ | Thread secondThread = new Thread(new Runnable() { | ||
+ | @Override | ||
+ | public void run() { | ||
+ | ProgramState.person.firstName = "James"; | ||
+ | } | ||
+ | }); | ||
+ | System.out.println(ProgramState.person.firstName); // => Jessie | ||
+ | secondThread.start(); | ||
+ | secondThread.join(); | ||
+ | System.out.println(ProgramState.person.firstName); // => James | ||
+ | } | ||
+ | }</syntaxhighlight> | ||
+ | |||
+ | A <code>static</code> member variable in D is local to the ''current thread only'', known as thread-local storage. Every thread you create will have a different version of your <code>static</code> member variables. | ||
+ | To have the same behaviour as Java in D, you need to use the <code>__gshared</code> type qualifier. | ||
+ | |||
+ | <syntaxhighlight lang="D">import core.thread; | ||
+ | |||
+ | class Person | ||
+ | { | ||
+ | string firstName; | ||
+ | |||
+ | this(string fname) { | ||
+ | firstName = fname; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | class ProgramState | ||
+ | { | ||
+ | __gshared static Person person; | ||
+ | |||
+ | static this() | ||
+ | { | ||
+ | person = new Person("Jessie"); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void main() | ||
+ | { | ||
+ | new ProgramState(); | ||
+ | Thread secondThread = new Thread(() { | ||
+ | ProgramState.person.firstName = "James"; | ||
+ | }); | ||
+ | assert("Jessie" == ProgramState.person.firstName); | ||
+ | secondThread.start(); | ||
+ | secondThread.join(); | ||
+ | assert("James" == ProgramState.person.firstName, "firstName is not James"); | ||
+ | }</syntaxhighlight> | ||
+ | |||
+ | Removing the <code>__gshared</code> from the above snippet will result in the second assertion failing as <code>ProgramState.person.firstName</code> will be <code>"Jessie"</code>. | ||
+ | |||
+ | For an overview of the different forms of concurrency, see the [https://ddili.org/ders/d.en/concurrency_shared.html Data Sharing Concurrency] chapter in ''Programming in D'' which also explains one of D's preferred way of sharing variables between threads: <code>shared</code>. | ||
[[Category:Languages versus D]] | [[Category:Languages versus D]] |
Revision as of 10:06, 26 August 2023
Downcasting
The Java way
if (animal instanceof Cat)
{
Cat cat = (Cat) animal;
/* use cat */
}
The D way
if(auto cat = cast(Cat) animal)
{
/* use cat */
}
Static Class Member Variables
In Java if you declare a member variable as static
it will be stored in global storage for the entire program, allowing you to access the same reference from multiple threads.
class Person {
public String firstName;
public Person(String fname) {
this.firstName = fname;
}
}
class ProgramState {
public static Person person;
static {
person = new Person("Jessie");
}
}
public class Program {
public static void main(String[] args) throws Exception {
new ProgramState();
Thread secondThread = new Thread(new Runnable() {
@Override
public void run() {
ProgramState.person.firstName = "James";
}
});
System.out.println(ProgramState.person.firstName); // => Jessie
secondThread.start();
secondThread.join();
System.out.println(ProgramState.person.firstName); // => James
}
}
A static
member variable in D is local to the current thread only, known as thread-local storage. Every thread you create will have a different version of your static
member variables.
To have the same behaviour as Java in D, you need to use the __gshared
type qualifier.
import core.thread;
class Person
{
string firstName;
this(string fname) {
firstName = fname;
}
}
class ProgramState
{
__gshared static Person person;
static this()
{
person = new Person("Jessie");
}
}
void main()
{
new ProgramState();
Thread secondThread = new Thread(() {
ProgramState.person.firstName = "James";
});
assert("Jessie" == ProgramState.person.firstName);
secondThread.start();
secondThread.join();
assert("James" == ProgramState.person.firstName, "firstName is not James");
}
Removing the __gshared
from the above snippet will result in the second assertion failing as ProgramState.person.firstName
will be "Jessie"
.
For an overview of the different forms of concurrency, see the Data Sharing Concurrency chapter in Programming in D which also explains one of D's preferred way of sharing variables between threads: shared
.