
| Feature | Java | C++ |
| Constructs | Class interface package. | Class, structs, typedefs, procs. |
| Accessing objects | Object refs: obj.member | Pointers and objects: obj.member, objp->member |
| Object creation: | new | new and on the stack |
| Initialization | Constructor | Ctor,copy ctor |
| Object destruction: | Garbage collected | delete and block exit |
| De-Initialization | Finalize | Destructor |
| Access | Public, private, protected, package | Public, private, protected, friend |
| Dynamic binding | Default | Virtual |
| Non-Dynamic binding | Final | None |
| Abstract Class | abstract | Pure virtual function |
public class HelloWorld {
public static void main(String args[])
{
System.out.println("Hello World");
}
}
In Java everything is in a class, there are no procedures,
variables, etc.
All objects are created with new:
SomeObject obj = new SomeObject();and referenced as:
obj.SomeMethod();Constructors are called on a new, but there are no destructors. Objects are garbage collected and one does not explicitly call delete. Reather, when an object is garbage collected the method
finalize
is called.
[ClassModifiers] class className
[extends superClass]
[implements interfaces] {
...
}
abstract - Not actually implemented final - No subclasses allowed public - Exports this class outside of package. One per file. File must be named ClassName.java private - Can only be used inside of file.
public -
protected -
private -
final - cannot be redefined in derived class
static
synchronized - calls go through a monitor
native - stub that calls native implementation
So what would this do for us:
final class SomeClass {
private SomeClass() {}
public static DoSomething() {}
public static DoSomethingElse() {}
}
In ObjArray.java:
package Collection;
public class ObjArray {
...
In ObjList.java:
package Collection;
public class ObjList {
...
Now when we use this:
import Collection.*;
class Runnable {
public:
virtual void Tick(){}
};
class Command : public Runnable {
void Tick(){
DoSomething();
}
};
class Window : public Runnable {
void Tick(){
Refresh();
}
};
void EventLoop(){
while(1){
for runnable in Runnables
runnable->Tick();
}
}
So to implement a producer/consumer model we could:
List buffer;
class Producer : public Runnable {
void Tick(){
buffer.Insert(some_data);
}
};
class Consumer : public Runnable {
void Tick(){
buffer.Remove();
}
};
class Buffer extends List {
synchronized public Object* RemoveData ()
{
return ...
}
synchronized public Object* InsertData ()
{
insert ...
}
public synchronized bool HasData(){
return ...
}
}
class Producer implements Runnable {
public Thread myThread;
Buffer myBuffer
public Producer(Buffer b){
myThread = new Thread(this);
myBuffer = b;
}
void Run(){
while(true){
b.InsertData(GenerateData());
}
}
}
class Consumer implements Runnable {
public Thread myThread;
Buffer myBuffer
public Consumer(Buffer b){
myThread = new Thread(this);
myBuffer = b;
}
void Run(){
if(b.HasData(...)){
b.RemoveData();
}
}
}
class App {
static public main(){
Buffer b = new Buffer();
Producer p1 = new Producer(b);
Consumer c1 = new Consumer(b);
c1.myThread.start();
p1.myThread.start();
}
}
or multiple producers and consumers:
class App {
static public main(){
Buffer b = new Buffer();
Producer p1 = new Producer(b);
Producer p2 = new Producer(b);
Producer p3 = new Producer(b);
Consumer c1 = new Consumer(b);
Consumer c2 = new Consumer(b);
Consumer c3 = new Consumer(b);
c1.myThread.start();
p1.myThread.start();
c2.myThread.start();
p2.myThread.start();
c3.myThread.start();
p3.myThread.start();
}