Sunday, September 19, 2021

Variable Declarations

 There are two types of variables in Java:

Primitives A primitive can be one of eight types: char, boolean, byte,
short, int, long, double, or float. Once a primitive has been declared,
its primitive type can never change, although in most cases its value can
change.

Reference variables A reference variable is used to refer to (or access) an
object. A reference variable is declared to be of a specific type, and that type
can never be changed. A reference variable can be used to refer to any object
of the declared type or of a subtype of the declared type (a compatible type). 

Declaring Primitives and Primitive Ranges

Primitive variables can be declared as class variables (statics), instance variables,
method parameters, or local variables. You can declare one or more primitives, of the
same primitive type, in a single line. 

byte b;
boolean myBooleanPrimitive;
int x, y, z; // declare three int primitives






Declaring Reference Variables
Reference variables can be declared as static variables, instance variables, method
parameters, or local variables. You can declare one or more reference variables, of
the same type, in a single line.

Object o;
Dog myNewDogReferenceVariable;
String s1, s2, s3; // declare three String vars.

Instance Variables
Instance variables are defined inside the class, but outside of any method, and are
initialized only when the class is instantiated. Instance variables are the fields that
belong to each unique object. For example, the following code defines fields
(instance variables) for the name, title, and manager for employee objects:
class Employee {
// define fields (instance variables) for employee instances
private String name;
private String title,
private String manager;
// other code goes here including access methods for private
// fields
}

Can use any of the four access levels (which means they can be marked with
any of the three access modifiers)
Can be marked final
Can be marked transient
Cannot be marked abstract
Cannot be marked synchronized
Cannot be marked strictfp
Cannot be marked native
Cannot be marked static, because then they'd become class variables
Static Variables and Methods
The static modifier is used to create variables and methods that will exist
independently of any instances created for the class. All static members exist
before you ever make a new instance of a class, and there will be only one copy of a60 Chapter 1: Declarations and Access Control
static member regardless of the number of instances of that class. In other words,
all instances of a given class share the same value for any given static variable.
We'll cover static members in great detail in the next chapter.

Things you can mark as static:

Methods
Variables
A class nested within another class, but not within a method 
Initialization blocks

Things you can't mark as static:

Constructors (makes no sense; a constructor is used only to create instances)
Classes (unless they are nested)
Interfaces (unless they are nested)
Method local inner classes 
Inner class methods and instance variables
Local variables 











Saturday, September 18, 2021

Declare Class Members

Access Modifiers

Whereas a class can use just two of the four access control levels (default or
public), members can use all four:
public
protected
default
private

You need to understand two different access issues:


Whether method code in one class can access a member of another class
Whether a subclass can inherit a member of its superclass

The first type of access occurs when a method in one class tries to access a
method or a variable of another class, using the dot operator (.) to invoke a method
or retrieve a variable. For example:
class Zoo {
public String coolMethod() {
return "Wow baby";
}
}
class Moo {
public void useAZoo() {
Zoo z = new Zoo();
// If the preceding line compiles Moo has access
// to the Zoo class
// But... does it have access to the coolMethod()?
System.out.println("A Zoo says, " + z.coolMethod());
// The preceding line works because Moo can access the
// public method
}
}

The second type of access revolves around which, if any, members of a superclass
a subclass can access through inheritance. We're not looking at whether the subclass
can, say, invoke a method on an instance of the superclass (which would just be an
example of the first type of access). Instead, we're looking at whether the subclass
inherits a member of its superclass.


class Zoo {
public String coolMethod() {
return "Wow baby";
}
}
class Moo extends Zoo {
public void useMyCoolMethod() {
// Does an instance of Moo inherit the coolMethod()?
System.out.println("Moo says, " + this.coolMethod());
// The preceding line works because Moo can inherit the
// public method
// Can an instance of Moo invoke coolMethod() on an

// instance of Zoo?

 Zoo z = new Zoo();
System.out.println("Zoo says, " + z.coolMethod());
// coolMethod() is public, so Moo can invoke it on a Zoo
// reference
}
}

Public Members

When a method or variable member is declared public, it means all other classes,
regardless of the package they belong to, can access the member (assuming the class
itself is visible).
Look at the following source file:
package book;
import cert.*; // Import all classes in the cert package
class Goo {
public static void main(String[] args) {
Sludge o = new Sludge();
o.testIt();
}
}
Now look at the second file:
package cert;
public class Sludge {
public void testIt() { System.out.println("sludge"); }
}


For a subclass, if a member of its superclass is declared public, the subclass
inherits that member regardless of whether both classes are in the same package:
package cert;
public class Roo {
public String doRooThings() {
// imagine the fun code that goes here
return "fun";
}
}

Private Members
Members marked private can't be accessed by code in any class other than the
class in which the private member was declared. Let's make a small change to the
Roo class from an earlier example:
package cert;
public class Roo {
private String doRooThings() {
// imagine the fun code that goes here, but only the Roo
// class knows

return "fun";
}
}
The doRooThings() method is now private, so no other class can use it. If we
try to invoke the method from any other class, we'll run into trouble:
package notcert;
import cert.Roo;
class UseARoo {
public void testIt() {
Roo r = new Roo(); //So far so good; class Roo is public
System.out.println(r.doRooThings()); // Compiler error!
}
}

Protected and Default Members
The protected and default access control levels are almost identical, but with one
critical difference. A default member may be accessed only if the class accessing the
member belongs to the same package, whereas a protected member can be accessed (through inheritance) by a subclass even if the subclass is in a different package. Take a look at the following two classes:

package certification;
public class OtherClass {
void testIt() { // No modifier means method has default
// access
System.out.println("OtherClass");
}
}




In another source code file you have the following:
package somethingElse;
import certification.OtherClass;
class AccessClass {
static public void main(String[] args) {
OtherClass o = new OtherClass();
o.testIt();
}
}

Protected Details
Let's take a look at a protected instance variable (remember, an instance variable
is a member) of a superclass.
package certification;
public class Parent {
protected int x = 9; // protected access
}
The preceding code declares the variable x as protected. This makes the
variable accessible to all other classes inside the certification package, as well as
inheritable by any subclasses outside the package.
Now let's create a subclass in a different package, and attempt to use the variable
x (that the subclass inherits):
package other; // Different package
import certification.Parent;
class Child extends Parent {
public void testIt() {
System.out.println("x is " + x); // No problem; Child
// inherits x
}
}

Local Variables and Access Modifiers
There is never a case where an access modifier can be applied to a local variable,
so watch out for code like the following:
class Foo {
void doStuff() {
private int x = 7;
this.doMore(x);
}
}
You can be certain that any local variable declared with an access modifier will
not compile. In fact, there is only one modifier that can ever be applied to local
variables—final.



Nonaccess Member Modifiers:

Final Methods
The final keyword prevents a method from being overridden in a subclass, and is
often used to enforce the API functionality of a method.

class SuperClass{
public final void showSample() {
System.out.println("One thing.");
}
}
Final Arguments

Method arguments are the variable declarations that appear in between the
parentheses in a method declaration. A typical method declaration with multiple
arguments looks like this:

public Record getRecord(int fileNumber, int recNumber) {}

Method arguments are essentially the same as local variables. In the preceding
example, the variables fileNumber and recNumber will both follow all the rules
applied to local variables. This means they can also have the modifier final:
public Record getRecord(int fileNumber, final int recNumber) {} 

Abstract Methods
An abstract method is a method that's been declared (as abstract) but not
implemented. In other words, the method contains no functional code. And if you
recall from the earlier section "Abstract Classes," an abstract method declaration
doesn't even have curly braces for where the implementation code goes, but instead
closes with a semicolon. In other words, it has no method body. You mark a method
abstract when you want to force subclasses to provide the implementation.

public abstract void showSample();
Notice that the abstract method ends with a semicolon instead of curly braces.
It is illegal to have even a single abstract method in a class that is not explicitly
declared abstract! Look at the following illegal class:
public class IllegalClass{
public abstract void doIt();
}

The method is not marked abstract.
The method declaration includes curly braces, as opposed to ending in a
semicolon. In other words, the method has a method body.
The method might provide actual implementation code inside the curly braces.

The first concrete subclass of an abstract class must implement all abstract
methods of the superclass.

Synchronized Methods
The synchronized keyword indicates that a method can be accessed by only one
thread at a time.
public synchronized Record retrieveUserInfo(int id) { }
You should also know that the synchronized modifier can be matched with any
of the four access control levels (which means it can be paired with any of the three
access modifier keywords).

Native method:
The native modifier indicates that a method is implemented in platform-dependent
code native is a modifier (thus a reserved keyword) and that native can be applied only to methods—not classes, not variables, just methods. Note that a native method's body must be a semicolon (;) (like abstract methods), indicating that the implementation is omitted. 

Strictfp Methods

We looked earlier at using strictfp as a class modifier, but even if you don't
declare a class as strictfp, you can still declare an individual method as strictfp.
Remember, strictfp forces floating points (and any floating-point operations) to
adhere to the IEEE 754 standard. With strictfp, you can predict how your floating
points will behave regardless of the underlying platform the JVM is running on.

Methods with Variable Argument Lists (var-args)
As of Java 5, Java allows you to create methods that can take a variable number of
arguments.

As a bit of background, we'd like to clarify how we're going to use the terms
"argument" and "parameter" throughout this book.
arguments The things you specify between the parentheses when you're
invoking a method:
doStuff("a", 2); // invoking doStuff, so "a" & 2 are
// arguments
parameters The things in the method's signature that indicate what the
method must receive when it's invoked:
void doStuff(String s, int a) { } // we're expecting two
// parameters:
// String and int
We'll cover using var-arg methods more in the next few chapters; for now let's
review the declaration rules for var-args:

Var-arg type When you declare a var-arg parameter, you must specify the
type of the argument(s) this parameter of your method can receive. (This can
be a primitive type or an object type.)

Basic syntax To declare a method using a var-arg parameter, you follow the
type with an ellipsis (...), a space, and then the name of the array that will
hold the parameters received.

Other parameters It's legal to have other parameters in a method that uses
a var-arg.

Var-arg limits The var-arg must be the last parameter in the method's
signature, and you can have only one var-arg in a method.
Let's look at some legal and illegal var-arg declarations:
Legal:
void doStuff(int... x) { } // expects from 0 to many ints
// as parameters
void doStuff2(char c, int... x) { } // expects first a char,
// then 0 to many ints
void doStuff3(Animal... animal) { } // 0 to many Animals
Illegal:
void doStuff4(int x...) { } // bad syntax
void doStuff5(int... x, char... y) { } // too many var-args
void doStuff6(String... s, byte b) { } // var-arg must be last

Constructor Declarations
In Java, objects are constructed. Every time you make a new object, at least one
constructor is invoked. Every class has a constructor, although if you don't create
one explicitly, the compiler will build one for you. 
class Foo {
protected Foo() { } // this is Foo's constructor
protected void Foo() { } // this is a badly named, but legal, method
}


Variable Declarations

  There are two types of variables in Java: ■ Primitives A primitive can be one of eight types: char , boolean , byte , short , int , long...