Differencebetween Declaration and Definition in Java

What is the difference between declaration and definition in Java?

The conceptual difference is simple:

  • Declaration: You are declaring that something exists, such as a class, function or variable. You don't say anything about what that class or function looks like, you just say that it exists.

  • Definition: You define how something is implemented, such as a class, function or variable, i.e. you say what it actually is.

In Java, there is little difference between the two, and formally speaking, a declaration includes not only the identifier, but also it's definition. Here is how I personally interpret the terms in detail:

  • Classes: Java doesn't really separate declarations and definitions as C++ does (in header and cpp files). You define them at the point where you declare them.

  • Functions: When you're writing an interface (or an abstract class), you could say that you're declaring a function, without defining it. Ordinary functions however, are always defined right where they are declared. See the body of the function as its definition if you like.

  • Variables: A variable declaration could look like this:

    int x;

    (you're declaring that a variable x exists and has type int) either if it's a local variable or member field. In Java, there's no information left about x to define, except possible what values it shall hold, which is determined by the assignments to it.

Here's a rough summary of how I use the terms:

abstract class SomeClass {                // class decl.
// \
int x; // variable decl. |
// |
public abstract void someMethod(); // function decl. |
// |
public int someOtherMethod() { // function decl. |
// | class
if (Math.random() > .5) // \ | def.
return x; // | function definition |
else // | |
return -x; // / |
// |
} // |
} // /

Declaring vs Defining - Java

String str; //declaraing
str = "My String"; //defining

Java: define terms initialization, declaration and assignment

assignment: throwing away the old value of a variable and replacing it with a new one

initialization: it's a special kind of assignment: the first. Before initialization objects have null value and primitive types have default values such as 0 or false. Can be done in conjunction with declaration.

declaration: a declaration states the type of a variable, along with its name. A variable can be declared only once. It is used by the compiler to help programmers avoid mistakes such as assigning string values to integer variables. Before reading or assigning a variable, that variable must have been declared.

What distinguishes the declaration, the definition and the initialization of a variable?

Declaration

Declaration, generally, refers to the introduction of a new name in the program. For example, you can declare a new function by describing it's "signature":

void xyz();

or declare an incomplete type:

class klass;
struct ztruct;

and last but not least, to declare an object:

int x;

It is described, in the C++ standard, at §3.1/1 as:

A declaration (Clause 7) may introduce one or more names into a translation unit or redeclare names introduced by previous declarations.

Definition

A definition is a definition of a previously declared name (or it can be both definition and declaration). For example:

int x;
void xyz() {...}
class klass {...};
struct ztruct {...};
enum { x, y, z };

Specifically the C++ standard defines it, at §3.1/1, as:

A declaration is a definition unless it declares a function without specifying the function’s body (8.4), it contains the extern specifier (7.1.1) or a linkage-specification25 (7.5) and neither an initializer nor a function- body, it declares a static data member in a class definition (9.2, 9.4), it is a class name declaration (9.1), it is an opaque-enum-declaration (7.2), it is a template-parameter (14.1), it is a parameter-declaration (8.3.5) in a function declarator that is not the declarator of a function-definition, or it is a typedef declaration (7.1.3), an alias-declaration (7.1.3), a using-declaration (7.3.3), a static_assert-declaration (Clause 7), an attribute- declaration (Clause 7), an empty-declaration (Clause 7), or a using-directive (7.3.4).

Initialization

Initialization refers to the "assignment" of a value, at construction time. For a generic object of type T, it's often in the form:

T x = i;

but in C++ it can be:

T x(i);

or even:

T x {i};

with C++11.

Conclusion

So does it mean definition equals declaration plus initialization?

It depends. On what you are talking about. If you are talking about an object, for example:

int x;

This is a definition without initialization. The following, instead, is a definition with initialization:

int x = 0;

In certain context, it doesn't make sense to talk about "initialization", "definition" and "declaration". If you are talking about a function, for example, initialization does not mean much.

So, the answer is no: definition does not automatically mean declaration plus initialization.

How does declaration, definition and initialization work? I've stated how I understand it and would like to get corrected

Yes, in simple terms you are correct. The standard draft devotes a page or so to declarations and definitions in par. 6.1. I liked how it described declarations (emphasis by me):

A declaration (Clause 10) may introduce one or more names into a translation unit or redeclare names
introduced by previous declarations.

The standard is vague about the nature of these names (in particular it doesn't mention "objects", "variables" or "types"!) because there is a great variety: Classes, functions, enum declarators, plain old variables, parameters, static class members etc.

The standard is also vague about the nature of this "introduction" because it varies as well. The common denominator is that a declaration gives the compiler enough information about the name to work with it it, although perhaps only in a restricted manner. For example, after the forward declaration of a class (class MyClass;) the compiler knows only that the name designates a type; but that's enough to define pointers to it (because all pointers to objects are created equal). It is not enough though to create an object of that type or call a method: The data and function members are, after all, unknown.

One can probably say that a declaration often specifies the outward properties — enough to use a name in some manner —, while a definition specifies the inner workings, i.e. what happens when it is being used.

For example, probably the most common "pure" declarations are function declarations, typically in headers. They inform the compiler how they can be called and which code must be produced to call them. A function definition, by contrast, specifies what happens when the function is called.

Similarly for a variable declaration vs. definition: *How can it be used vs. what happens when it is being used (which memory is manipulated).

The standard then goes on for half a page to list declarations which are not also definitions; about 10% of that are unknown terms for me (not sure whether that reflects badly on the standard or on me). With variables though, a declaration is, as you said, typically a definition unless it comes with the extern specifier and no initialization.

Difference between declaration annotations and type annotations

Both type annotations and declaration annotations still exist in Java, and they are distinct and non-overlapping.

A type annotation can be written on any use of a type.
It conceptually creates a new, more specific type.
That is, it describes what values the type represents.

As an example, the int type contains values ..., -2, -1, 0, 1, 2, ...

The @Positive int type contains values 1, 2, ...

Therefore, @Positive int is a subtype of int.

A declaration annotation can be written on any declaration (a class, method, or variable). It describes the thing being declared, but does not describe run-time values. Here are examples of declaration annotations:

@Deprecated
class MyClass { ... }

says that programmers should not use MyClass.

@Override
void myMethod() { ... }

says that myMethod overrides a declaration in a superclass or interface.

@SuppressWarnings(...)
int myField = INITIALIZATION-EXPRESSION;

says that the compiler should not issue warnings about code in the initialization expression.

Here are examples that use both a declaration annotation and a type annotation:

@Override
@NonNull String myMethod() { ... }

@GuardedBy("myLock")
@Regex String myField;

Note that the type annotation describes the value, and the declaration annotation says something about the method or use of the field.

As a matter of style, declaration annotations are written on their own line, and type annotations are written directly before the type, on the same line.

Separate files for class definition and declaration in Java

There is a practical reason for separating declaration in C++, and it's to allow source files to be compiled separately. There is no such need in Java (as everything is compiled to bytecode separately), so it isn't allowed.



Related Topics



Leave a reply



Submit