why not import everything?

W

Wojtek

yawnmoth wrote :
Is there a particular reason why Java doesn't automatically do "import
java.*" for all programs? It can be specified manually, but I'm just
wondering why Java doesn't already do it. Indeed, there are quite a
few Java apps that don't do this and, instead, import classes one
import statement at a time.

I am working on a web applicatiob. Each use case has its own package.
It also has its own set of classes. To make maintenance easier, the
classes which perform the saame function have the same name. So each
use case has:

Command - business logic and the glue code between the database and the
other layers.
SQL - all the SQL code
Data - the data object which is passed around like a hot potato
Validate - validates user input
XXServlet - handles navigation and does command calls
XXPage - holds form fields

There are over 190 use cases.

A global import would cause havoc.
 
L

Lew

blueparty said:
Then, more often than not, you need to import your own packages, which
are, probably, not java.*, but still need to be imported.

Unless you're writing for the Java platform itself, and as you say one
probably is not, then you may not use 'java' or 'javax' as top-level
package names.

JLS s. 6.8.1:
 
B

blue indigo

There's a paradox of sorts here.

Without IDEs it's more of a pain in the butt to do single-class
imports, but it's much more important to do so. Without it, it's very
difficult for the maintainer to find what package the class lives in.

There's a fallacy of sorts here: an assumption that the developer using
or not using an IDE is perfectly correlated with the maintenance
programmer using or not using an IDE.

In particular, if the developer doesn't use an IDE doing single-class
imports (especially of Swing classes) is going to be a pain, and if the
maintenance programmer later on DOES use an IDE encountering star imports
is not going to be much of a pain. Click in identifier, then do a find
javadoc or find source, presto, you know where it came from.

Also, as someone else pointed out earlier in this thread, non-use of an
IDE is a choice, with Eclipse and NetBeans both free and, being
implemented in Java, available on pretty much any system a Java programmer
is likely to be programming on. About the only exception I can think of is
a text-mode system, perhaps because it's headless and remote. And that
also sounds like a choice, unless for some reason there's no remote access
to the repository. If there is, you can use Eclipse or NetBeans on a
graphical workstation, configured to use the repository; both of them
support the commonest version control systems.

(And even if there is not, there's probably an emacs mode that will do the
same sort of pointer-chasing. There seems to be an emacs mode for
everything, if that is you can stomach an essentially text-only interface.
Which you'd better if the only access to the code you're hacking is from a
text-only system.)
However, when working on a large system, it is unacceptable to create a
situation where programmer A's addtion of a new class breaks programmer
B's code. Neither A nor the person in charge of building the system as
a whole should be expected to go to B's code and figure out how to get
it working again.

This is much better reason to oppose star imports than that other one, and
is why I personally avoid using them.
 
A

Arne Vajhøj

Peter said:
But:

-- How often does that really happen? I'm not suggesting it never
does, but engaging in a dogmatic philosophy in order to make things
slightly easier in rare circumstances isn't necessarily a slam-dunk
argument

-- How hard is it really to fix the problem? In most cases, it
should be readily apparent which namespace has the newer class. And
even if it's not, the odds of the two classes having identical members
is pretty low. It should take a competent developer just a few minutes
to sort things out.

Sure, a few minutes happening over and over again is a waste of time and
should be avoided. But if that few minutes happens once every year or
so, but using wildcards makes authoring the code more efficient, the
latter might actually be the more efficient use of developer resources.

There is a difference in that all the single class imports will be
done by the developer working on the code and familiar with it. The
build errors after upgrades will often be rather inconvenient, the build
guy calls the tech lead and the tech lead need to track down a developer
responsible for that code that may not have been planned to be modified.
Finally, the fact is that there's a reason that Java and similar
languages introduced the idea of namespaces, and that's because in a
very real sense, many development environments that preceded them did in
fact have practically an "import all packages" approach.

For example, sure...C/C++ offers include files, and you can
theoretically partition the libraries you use with that mechanism (and
linking). But in Windows, an enormous amount of the native Win32 API is
declared in the include files that you get with just one include:
"windows.h". Yet, this sort of monolithic "import all" hasn't prevented
there being at least a few successful programs written in that context.

C++ has namespaces.
For what it's worth, C# has become a very popular programming language,
and you have to really go out of your way to _not_ effectively use a
wildcard import. So almost no one doesn't. Yet, for some reason, type
collisions don't seem to be dragging the C# community down. :)

It is possible though that since .NET programmers knows
this then they try to pick names that does not create
the conflict or even have to if they use the the conflicting
code themselves.

Arne
 
L

Lew

Peter said:
I share your preference for the supposed "non-best-practices" practice of
using wildcards in Java imports. Even though Eclipse defaults to the
non-wildcard import, I get tired of, for the namespaces with lots of stuff
I use from them, having to go back and keep adding new imports as I write
the code. When it adds a new import for a class that's in a namespace I
know I'll be dragging lots of other stuff in from, I just go make the
import use a wildcard. Then I get back to writing my code instead of
messing with imports.

How much trouble can keychording Ctrl-Shift-O be?

If you don't like to do it repeatedly, you can start with wildcards, then hit
the chord once to clean up and turn all into single-type imports.
 
M

Mike Schilling

Arne said:
It is possible though that since .NET programmers knows
this then they try to pick names that does not create
the conflict or even have to if they use the the conflicting
code themselves.

C# actually does allow single-class imports, but no one seems to use
them. That is,

1. I've never seen example code (from Microsoft or anyone else) that
uses them.
2. As far as I can tell Visual Studio doesn't help the developer
create them. (And for a large fraction of C# programmers, anything
not in VS might as well not be in the language.)
3. When I asked in Microsoft's C++ newsgroup whether people thought
that single-class imports were a good idea (as many of us do in Java)
most responses thought I was asking for a new feature.
 
R

RedGrittyBrick

Peter said:
I don't know. I wasn't even aware of that binding. If it can be done
immediately after typing the type name, thus addressing the issue of
auto-complete,

That's how I use it.
perhaps it's not a bad approach for those who really can't
stand having wildcard imports in their code.

I don't care either way but adding wildcard imports would feel like more
work to me. Even if I automatically added some wildcard boilerplate
imports to every .java file I created, my IDE would complain about
unused imports. I'll continue pressing Ctrl+Shift+O whenever a squiggly
red underline appears under a classname I've just typed. I like to
eliminate warnings and errors as I go. YMMV.
Why can't the person trying to figure out what package a type came from do
the same?

As a reader of someone else's code, I am reluctant to change the code I
am trying to debug before I think I understand it. I agree that
sometimes the easiest way is just to put the code into an IDE and have
the IDE reformat it the way you find easiest to deal with. It's nicer to
not have to. It's a minor point.

Figuring out List came from java.util.* isn't hard but I expect there's
some more obscure examples that would be harder to work out,
particularly as packages gain classes over time. Maybe seeing
SwingWorker in old code, it might not be obvious if it is Java 6
SwingWorker, SwingWorker 3 or a backport? Maybe this isn't a problem in
practice?

Seems like a solution in search of a problem to me.

I find it useful that my IDE manages imports for me. Since it auto-folds
imports I almost never have to give them any attention. Before I started
using an IDE, imports often felt like a tedious nuisance. YMMV.
 
A

Arne Vajhøj

Mike said:
C# actually does allow single-class imports, but no one seems to use
them. That is,

1. I've never seen example code (from Microsoft or anyone else) that
uses them.
2. As far as I can tell Visual Studio doesn't help the developer
create them. (And for a large fraction of C# programmers, anything
not in VS might as well not be in the language.)
3. When I asked in Microsoft's C++ newsgroup whether people thought
that single-class imports were a good idea (as many of us do in Java)
most responses thought I was asking for a new feature.

C++ or C# ?

If it is C++ then the problem is well known and Bjarne himself
is strongly advocating against using'ing entire namespaces.

Arne
 
L

Lew

RedGrittyBrick said:
Figuring out List came from java.util.* isn't hard but I expect there's
some more obscure examples that would be harder to work out,
particularly as packages gain classes over time. Maybe seeing
SwingWorker in old code, it might not be obvious if it is Java 6
SwingWorker, SwingWorker 3 or a backport? Maybe this isn't a problem in
practice?

A few months ago I was porting some 1.3/1.4 code to Java 5 for a project.
They were using a backport of java.util.concurrent that was not in java.util
but the in the backport domain (edu.cornell something, IIRC). It comes up in
practice.
I find it useful that my IDE manages imports for me. Since it auto-folds
imports I almost never have to give them any attention. Before I started
using an IDE, imports often felt like a tedious nuisance. YMMV.

I find this aversion to detail, such as hating one-type imports and using
import-on-demand, or avoiding repetition of type parameters in the declaration
and the 'new' expression, symptomatic of the "I don't want to write any extra
keystrokes, no matter how much that ends up distressing the maintenance
programmer" laziness that abounds.

What's a few extra keystrokes, even if the IDE didn't eliminate most of them?
 
J

Joshua Cranmer

Lew said:
I find this aversion to detail, such as hating one-type imports and
using import-on-demand, or avoiding repetition of type parameters in the
declaration and the 'new' expression, symptomatic of the "I don't want
to write any extra keystrokes, no matter how much that ends up
distressing the maintenance programmer" laziness that abounds.

The only complaint I have about generics parameter in new is that it's a
bit painful if you're using 80-character widths [1]. Then I remember
that I'm writing a generics Pair utility class and add in
Pair.makePair() static function and forget all about those extra
characters. :)

[1] Yes, I'm still using 80-width rules. I actually develop Java with
<favorite text editor here> in tiled 80x24 xterms.
 
B

blue indigo

For me, the number of keystrokes used isn't an issue. My aversion is
to things that cause a distraction, making me have to interrupt my train
of thought.

Because typing ctrl-shift-I (or ctrl-shift-O, as the case may be) is such
a distraction.
 
L

Lew

Peter said:
That said, I've been poking around the key bindings in Eclipse (running on  
my Mac) and I haven't found a command that actually does this.  The ones  
named in this thread aren't doing anything, and the one that looks like  
the most likely candidate ("shift-command-M") seems to add the import  
statement sometimes, but not other times.  I haven't figured out what the  
difference is.

Things must be different on a Mac from Windows or Linux PCs. In every
variant of Eclipse (Ganymede, Rational Application Developer, Rational
Software Architect) that I've used on a PC, the menu item "Source /
Organize Imports" is mapped to Ctrl-Shift-O. The action replaces all
imports-on-demand with single-type imports. For example, just now I
opened Ganymede (in Windows) to a .java file that used
java.io.Serializable and java.util.Date. I gave it the imports

import java.io.*;
import java.util.*;

and hit Ctrl-Shift-O. Eclipse immediately replaced the wildcard
imports with

import java.io.Serializable;
import java.util.Date;

Does your Mac-based Eclipse have the menu item "Source / Organize
Imports"? If so, what is the key binding for that action?
 
D

Daniel Pitts

Peter said:
[...]
I find this aversion to detail, such as hating one-type imports and
using import-on-demand, or avoiding repetition of type parameters in
the declaration and the 'new' expression, symptomatic of the "I don't
want to write any extra keystrokes, no matter how much that ends up
distressing the maintenance programmer" laziness that abounds.

For the record, I don't think anyone here expressed that particular
aversion. I certainly didn't. For me, the number of keystrokes used
isn't an issue. My aversion is to things that cause a distraction,
making me have to interrupt my train of thought.

Pete
Then don't write the import statements until you've finished your train
of thoughts. If you forget to write them, its not a big deal, the
compiler will remind you soon enough.
 
M

Mike Schilling

Peter said:
I realize I can always come back after the fact and change the
imports
(even without the key binding, there's the menu command which as a
one-time-event is practically as easy to use), but it seems to me
that if a wildcard import is sufficient at some point in the
development process, it's sufficient at other points.

Really? Perhaps because I've been developing in teams for so long, it
seems obvious to me that there's a difference between what's
sufficient for code for which I'm the only audience and what's
sufficient for code that I've shared with the rest of the team (i.e.
checked into the SCM system.) The shared code requires full javadoc,
commenting of anything that isn't clear in itself, unit tests [1], and
single-class imports reduced only to classes actually imported.
Fortunately, most IDEs [2] make this last item easy these days.

1. A large discussion in itself, of course.
2. My favorite is IntelliJ Idea, but Eclipse works too.
 
L

Lew

[...]
Does your Mac-based Eclipse have the menu item "Source / Organize
Imports"?  If so, what is the key binding for that action?

Ah, I see.  Yes, it has the menu option.  The key sequence is  
"shift-command-O".

But, now I'm puzzled as to how that's supposed to address the issue of  
writing the import in the first place, which is what I was talking about.  
I didn't really understand what was being suggested here, until just now.

Ctrl-Shift-O does that, too. Even if you don't have a wildcard import
in place.
My concern was in the process of writing the code in the first place.  
What I'm looking for is a command that, having typed the name of a type,  
will immediately add an import for that type (displaying a context menu  
when the type name is present in multiple packages).  As I mentioned,  
"shift-command-M" (bound to the "Add Import" menu command) does that, but  
only sometimes.  :(

It's the same command - Ctrl-Shift-O (Shift-Command-O for you). We
keep suggesting it - have you tried it?
I realize I can always come back after the fact and change the imports  
(even without the key binding, there's the menu command which as a  
one-time-event is practically as easy to use), but it seems to me that if  
a wildcard import is sufficient at some point in the development process,  
it's sufficient at other points.

Unless you're the maintenance programmer who's trying to work with it
after the fact, as others have pointed out.
Obviously opinions differ.  :)

It's the same command: "Source / Organize Imports". Whether or not
there's a wildcard import in place, it'll seek out all possible
packages in the classpath that include the types you've used, and plug
in the single-type imports for them.

As people keep suggesting.

Autocomplete also fills in the single-type import in Eclipsen. For
example, if (after already importing 'java.util.List') you typed

List<Foo> stuff = new ArrayLi

then typed "Ctrl-Space" (on PCs - don't know about Mac), you'll get a
menu of possible completions that includes
'ArrayList' (java.util.ArrayList). (If you've set your options to do
so, it'll skip the menu and just fill in the type for you if there's
only one choice.) Select that from the menu and the line becomes

List<Foo> stuff = new ArrayList<Foo>

(waiting for you to type the parentheses), and
import java.util.ArrayList;
will have automagically appeared at the top of the source.

So "Ctrl-Space" is another keychord you want. As well as "Ctrl-Shift-
O", as noted above and upthread. (Or the Mac's equivalents, or the
menu item equivalents.)
 
L

Lew

Peter said:
[...]
I find this aversion to detail, such as hating one-type imports and
using import-on-demand, or avoiding repetition of type parameters in
the declaration and the 'new' expression, symptomatic of the "I don't
want to write any extra keystrokes, no matter how much that ends up
distressing the maintenance programmer" laziness that abounds.
For the record, I don't think anyone here expressed that particular
aversion.  I certainly didn't.  For me, the number of keystrokes used
isn't an issue.  My aversion is to things that cause a distraction,
making me have to interrupt my train of thought.

Then don't write the import statements until you've finished your train
of thoughts. If you forget to write them, its not a big deal, the
compiler will remind you soon enough.

Especially once you get used to it, but even from the get-go I
predict, using Ctrl-Space or Ctrl-Shift-O (or the Mac equivalents) as
you go fills in the imports (single-type), eliminates the syntax-error
indicator (wavy red line in Eclipse) and positions the cursor
appopriately, all with little or no break in one's train of thought.

Don't knock it until you've tried it.
 
I

Ian Pilcher

Knute said:
I don't know about that. Why would they give you the capability to
import a whole package and then not want you to use it? On the
contrary, writing all those import statements is sort of silly when you
can just import the package. The compiler is smart enough to tell you
if there is a conflict.

import java.foo.*;
import java.bar.*;
import java.baz.*;

Class WTF
{
public static void main(String[] args)
{
Thing t = new Thing(args);
}
}

You've just been told to enhance/debug/audit this code. Where are you
going to look to figure out what a Thing is?
 

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

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top