"Hello world!" without a public class?

A

Arne Vajhøj

»class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); // Display the string.
}
}
«

http://docs.oracle.com/javase/tutorial/getStarted/cupojava/win32.html

There is no »public« in front of »class« in Oracles Tutorial!

What should I teach in my classes?

1.) »public class HelloWorldApp« (because this is most common IIRC)

2.) »class HelloWorldApp« (because this is in Oracles tutorial)

3.) »final class HelloWorldApp« (because this class is not designed
for inheritance and Bloch says that one should not inherit from
it in this case and the students can as well get used to this
right from the start)

4.) »public final class HelloWorldApp« (combination of »1.)« and »3.)«)

'final' classes are useful for:

1) Safety. Not all classes can be subclassed safely. For example, a
subclass of Thread that starts itself from the constructor may be
executing the run() method before a subclass' constructor completes.
Another case would be data for which the equals() method can not be
generalized. Marking the class as final forces compile-time safety
against accidentally subclassing something that isn't ready for it.
Yes.

2) Security. Imagine the damage you could do if String was mutable.
You wouldn't want a credit card encryptor/decryptor to gain any extra
features because a mistake could cost millions of dollars.
Yes.

3) Performance. Methods known to have a single implementation can be
highly optimized by the JIT. This optimization must be removed as soon
as it's possible for there to be more than one implementation. This is
an awful side-effect that's difficult to trace. Classes requiring
maximum performance should be guarded from subclassing.

One can find that claim a gazillion places on the internet from
people you never heard about.

And then one can find:

http://www.ibm.com/developerworks/java/library/j-jtp1029/index.html

<quote>
The common perception is that declaring classes or methods final makes
it easier for the compiler to inline method calls, but this perception
is incorrect (or at the very least, greatly overstated).
</quote>

by Brian Goetz.

Arne
 
A

Arne Vajhøj

And get rid of one the most unreadable/widely abused parts of all
Java code? Sounds good to me... almost everything done with
inner/nested classes can be done cleaner with post 1.5 constructs
that do not require impossible to read code.

What post 1.5 constructs can replace inner classes?

Arne
 
A

Arne Vajhøj

Now that being said here is a good example of something that is easier
to read then either (yes it does get compiled into something very close
to inner classes [not nested if I remember the jargon correctly] but no
where near as ugly):
Foo.java:

public enum Foo
{
ACK {
public void doSomething(SomeClass arg)
{
do what ever for ACK
}
},
BAR {
public void doSomething(SomeClass arg)
{
do what ever for BAR
}
}
}

Fred.java:

public class Fred
{
public void someMethod()
{
SomeClass sc=new SomeClass(...);
Foo[] arr=new Foo[]{ACK,BAR}; // typing this for this example so being lazy on syntax

for(Foo elem:arr)
elem.doSomething(sc);
}
}

and voila much more readable then putting a whole rats nest of stuff in the initialization of arr
}
}

Given that the above is both unreadable and un-compilable, then ...

Arne
 
A

Arne Vajhøj

I'd probably go further and start students with a decent text editor and
command line calls for javac/java on the grounds that right from the
start they'll have a better understanding of the Java compilation and
runtime environment.

Once they're starting to write class hierarchies its time to introduce
packages, ant and jar. Why now? Because I found the later introduction of
these items to be confusing, requiring, as they did, a certain amount of
unlearning, particularly in connection with jar files, manifests and
classpaths.

I don't think students need to see an IDE until they start to find out
about refactoring. Again, I'd leave this as late ads possible for two
reasons: (1) IDEs generally have complex GUIs which can be quite
intimidating to a newbie, (2) they kick entirely too much stuff that a
programmer needs to know under the carpet: the build process, jarfile
creation, package management, version control - all things that I think
are best dealt with explicitly rather than being left to the IDE's magic
smoke and mirrors.

I agree that text editor and command line tools are important
to (see post I made after the one you replied to).

But when they have learned the basics, then they know what is
under the carpet and should start utilizing the benefits of the
IDE.

And people know sophisticated GUI's from other applications.

Arne
 
A

Aryeh M. Friedman

Now that being said here is a good example of something that is easier

to read then either (yes it does get compiled into something very close

to inner classes [not nested if I remember the jargon correctly] but no

where near as ugly):
public enum Foo

ACK {
public void doSomething(SomeClass arg)

do what ever for ACK


BAR {
public void doSomething(SomeClass arg)

do what ever for BAR






public class Fred

public void someMethod()

SomeClass sc=new SomeClass(...);
Foo[] arr=new Foo[]{ACK,BAR}; // typing this for this example so being lazy on syntax
for(Foo elem:arr)
elem.doSomething(sc);

and voila much more readable then putting a whole rats nest of stuff inthe initialization of arr

}



Given that the above is both unreadable and un-compilable, then ...



Arne

Ok here is some actual working code that effectively does the same thing with the psedocode filled in (including the command lines):

% cat Foo.java
public enum Foo
{
ACK {
public String doSomething(String arg)
{
return "ACK: "+arg;
}
},
BAR {
public String doSomething(String arg)
{
return "BAR: "+arg;
}
};

public abstract String doSomething(String arg);
}
% cat Fred.java
public class Fred
{
public static void main(String[] args)
{
for(Foo elem:new Foo[]{Foo.ACK,Foo.BAR})
System.out.println(elem.doSomething("I am doing something"));
}
}
% javac Fred.java
% java Fred
ACK: I am doing something
BAR: I am doing something

Now please tell me that does not replace inner classes (the enum constants are compiled as inner classes and not just straight data constants).
 
A

Arne Vajhøj

Given that the above is both unreadable and un-compilable, then ...

Ok here is some actual working code that effectively does the same thing with the psedocode filled in (including the command lines):

% cat Foo.java
public enum Foo
{
ACK {
public String doSomething(String arg)
{
return "ACK: "+arg;
}
},
BAR {
public String doSomething(String arg)
{
return "BAR: "+arg;
}
};

public abstract String doSomething(String arg);
}
% cat Fred.java
public class Fred
{
public static void main(String[] args)
{
for(Foo elem:new Foo[]{Foo.ACK,Foo.BAR})
System.out.println(elem.doSomething("I am doing something"));
}
}
% javac Fred.java
% java Fred
ACK: I am doing something
BAR: I am doing something

Now please tell me that does not replace inner classes (the enum constants are compiled as inner classes and not just straight data constants).

Well - now it compiles.

But:
1) you have made the code a lot more difficult to read by using
an enum for something non-enumish, and the same effect can
be had using normal classes just with a few more keywords
2) it is only relevant for static nested classes as it does not
provide the capturing the non-static nested classes do
3) it is only relevant for static nested classes that implements
not use that extends due to limitations on enum

In other words: no beef.

Arne
 
K

Kevin McMurtrie

Arne Vajhøj said:
»class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); // Display the string.
}
}
«

http://docs.oracle.com/javase/tutorial/getStarted/cupojava/win32.html

There is no »public« in front of »class« in Oracles Tutorial!

What should I teach in my classes?

1.) »public class HelloWorldApp« (because this is most common IIRC)

2.) »class HelloWorldApp« (because this is in Oracles tutorial)

3.) »final class HelloWorldApp« (because this class is not designed
for inheritance and Bloch says that one should not inherit from
it in this case and the students can as well get used to this
right from the start)

4.) »public final class HelloWorldApp« (combination of »1.)« and
»3.)«)

'final' classes are useful for:

1) Safety. Not all classes can be subclassed safely. For example, a
subclass of Thread that starts itself from the constructor may be
executing the run() method before a subclass' constructor completes.
Another case would be data for which the equals() method can not be
generalized. Marking the class as final forces compile-time safety
against accidentally subclassing something that isn't ready for it.
Yes.

2) Security. Imagine the damage you could do if String was mutable.
You wouldn't want a credit card encryptor/decryptor to gain any extra
features because a mistake could cost millions of dollars.
Yes.

3) Performance. Methods known to have a single implementation can be
highly optimized by the JIT. This optimization must be removed as soon
as it's possible for there to be more than one implementation. This is
an awful side-effect that's difficult to trace. Classes requiring
maximum performance should be guarded from subclassing.

One can find that claim a gazillion places on the internet from
people you never heard about.

And then one can find:

http://www.ibm.com/developerworks/java/library/j-jtp1029/index.html

<quote>
The common perception is that declaring classes or methods final makes
it easier for the compiler to inline method calls, but this perception
is incorrect (or at the very least, greatly overstated).
</quote>

by Brian Goetz.

Arne

The IBM article addresses a misconception about bytecode compilation.
Before high performance JITs, like Sun's HotSpot, compilers did make
extremely unsafe global optimizations based on the 'final' keyword.
That was nothing but trouble.

Making a class final and declaring instances of the class with that type
makes sure that optimizations are available.

abstract class Bitmap
{
abstract int getRGBA(int x, int y);
}


final class RGBA32Bitmap extends Bitmap
{
int getRGBA(int x, int y) {...}
}

Calling getRGBA() on a reference defined as class Bitmap will have
varying optimization during runtime depending on whether or not the
implementation can be guaranteed at a specific time. Sun's HotSpot may
add and remove optimizations as condition change. Calling getRGBA() on
a reference defined as class RGBA32Bitmap will be highly optimized at
runtime.

Of course I wouldn't bother with any of this unless it's needed.
 
L

Lew

Aryeh said:
On inner classes:
...
(yes it does get compiled into something very close to inner classes [notnested if I remember the jargon correctly]

Terminology: A nested type (class or interface) is a member of another type.
(JLS §8.5)

There are two kinds of nested classes, static and inner, per the JLS.
By definition, an inner class is a nested class whose declaration does not include the keyword 'static'.

"The static keyword may modify the declaration of a member type C within the
body of a non-inner class or interface T. Its effect is to declare that C is
not an inner class."
(JLS §8.5.1)
but no where near as ugly):

These get compiled exactly into inner classes.
Foo.java:

public enum Foo
{
ACK {
@Override

public void doSomething(SomeClass arg)
{
do what ever for ACK
}
},
...
}

In this case the enum, itself a cover for compiler-supported boilerplate for a
class with static constant members, also covers for the boilerplate of inner
class declarations in those constants.

Much as the lambdas I mentioned earlier cover for the boilerplate of inner-
class declarations of SAM interface implementations.

Neither of these work without inner classes, so your proposal to eliminate
inner classes would break them.
Fred.java:
...
and voila much more readable then putting a whole rats nest of stuff in the initialization of arr

Perhaps, but it doesn't prove the point, because it relies on inner classes..

And your claim that it's "much more readable" is not really proven.

public abstract class Bar
{
private final String rep;
abstract public void doSomething(Some arg);
private Bar(String r)
{
this.rep = r;
}
public static final BAR = new Bar("BAR")
{
@Override
public void doSomething(Some arg)
{
// do what ever for BAR
}
};
}

The only part of the anonymous class declaration that differs is the

new Bar("BAR")

Not even "much" different in readability, let alone "very much".
 
A

Arne Vajhøj

Arne Vajhøj said:
»class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); // Display the string.
}
}
«

http://docs.oracle.com/javase/tutorial/getStarted/cupojava/win32.html

There is no »public« in front of »class« in Oracles Tutorial!

What should I teach in my classes?

1.) »public class HelloWorldApp« (because this is most common IIRC)

2.) »class HelloWorldApp« (because this is in Oracles tutorial)

3.) »final class HelloWorldApp« (because this class is not designed
for inheritance and Bloch says that one should not inherit from
it in this case and the students can as well get used to this
right from the start)

4.) »public final class HelloWorldApp« (combination of »1.)« and
»3.)«)

'final' classes are useful for:

1) Safety. Not all classes can be subclassed safely. For example, a
subclass of Thread that starts itself from the constructor may be
executing the run() method before a subclass' constructor completes.
Another case would be data for which the equals() method can not be
generalized. Marking the class as final forces compile-time safety
against accidentally subclassing something that isn't ready for it.
Yes.

2) Security. Imagine the damage you could do if String was mutable.
You wouldn't want a credit card encryptor/decryptor to gain any extra
features because a mistake could cost millions of dollars.
Yes.

3) Performance. Methods known to have a single implementation can be
highly optimized by the JIT. This optimization must be removed as soon
as it's possible for there to be more than one implementation. This is
an awful side-effect that's difficult to trace. Classes requiring
maximum performance should be guarded from subclassing.

One can find that claim a gazillion places on the internet from
people you never heard about.

And then one can find:

http://www.ibm.com/developerworks/java/library/j-jtp1029/index.html

<quote>
The common perception is that declaring classes or methods final makes
it easier for the compiler to inline method calls, but this perception
is incorrect (or at the very least, greatly overstated).
</quote>

by Brian Goetz.

The IBM article addresses a misconception about bytecode compilation.
Before high performance JITs, like Sun's HotSpot, compilers did make
extremely unsafe global optimizations based on the 'final' keyword.
That was nothing but trouble.

Making a class final and declaring instances of the class with that type
makes sure that optimizations are available.

abstract class Bitmap
{
abstract int getRGBA(int x, int y);
}


final class RGBA32Bitmap extends Bitmap
{
int getRGBA(int x, int y) {...}
}

Calling getRGBA() on a reference defined as class Bitmap will have
varying optimization during runtime depending on whether or not the
implementation can be guaranteed at a specific time. Sun's HotSpot may
add and remove optimizations as condition change. Calling getRGBA() on
a reference defined as class RGBA32Bitmap will be highly optimized at
runtime.

Of course I wouldn't bother with any of this unless it's needed.

You may be disappointed if you ever decide that you need to
do it.

I would believe Brian Goetz over all the random statements
on the internet.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top