SlideShare a Scribd company logo
1 of 49
Effective Java
Third Edition
Chapter 4 – Classes and Interfaces
Item 15: Minimize the accessibility of
classes and members
Information hiding or encapsulation is important – decouples the components
Make each class or member as inaccessible as
possible.
Item 15: Minimize the accessibility of
classes and members
If a top-level class or interface can be made package-private, it should be.
public class A {...}
top-level class
class A {...}
package-private classs
Item 15: Minimize the accessibility of
classes and members
If class or interface is used by only one class, consider making it a private static
nested class of the sole class that uses it.
public class A {
....
private static class B {
...
}
}
B is ONLY used by A
Item 15: Minimize the accessibility of
classes and members
It is acceptable to make a private member of a public class package-private in
order to test it
public class A {
private void method() {...}
}
public class A {
void method() {...}
}
Cannot be tested Can be tested by Test Class
under the same package
Item 15: Minimize the accessibility of
classes and members
Instance fields of public classes should rarely be public.
public class A {
public String value1;
protected String value2;
}
public class A {
private String value1;
private String value2;
public String getValue1() {
return this.value1;
}
public String getValue() {
return this.value2;
}
}
Not invariants, can be
modified by outside or
subclass.
Item 15: Minimize the accessibility of
classes and members
It is wrong for a class to have a public static final array field, or an accessor that
returns such afield.
public class A {
public final static Thing[] VALUES = {...};
}
public class A {
private final static Thing[] VALUES = {...};
public static final Thing[] values() {
return VALUES;
}
}
WRONG! Security hole!,
public class A {
private final static Thing[] PRIVATE_VALUES = {...};
public static final List<Thing> values() {
return Collections
.unmodifiableList(
Arrays.asList(PRIVATE_VALUES));
}
public static final Thing[] values() {
return PRIVATE_VALUES.clone();
}
}
Item 15: Minimize the accessibility of
classes and members
Use Java 9 module system to share classes among packages within a module
without making them visible to the entire world.
Item 15: Minimize the accessibility of
classes and members
END
Item 16: In public classes, use accessor
methods, not public fields
class Point {
public double x;
public double y;
}
class Point {
private double x;
private double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() { return x; }
public double getY() { return y; }
public void setX(double x) { this.x = x; }
public void setY(double y) { this.y = y; }
}
NO encapsulation!!
• if a class is accessible outside its package (public class), provide accessor methods.
• public classes should never expose mutable fields.
Item 16: In public classes, use accessor
methods, not public fields
class A {
...
private class B {
public int value;
}
}
class A {
int value;
}
if a class is package-private or is a private nested class, there is
nothing inherently wrong with exposing its data fields
private nested class
package-private class
Item 16: In public classes, use accessor
methods, not public fields
END
Item 17: Minimize mutability
How to make a immutable class:
1. Don’t provide methods that modify the object’s state (No mutators/setters)
2. Ensure that the class can’t be extended.
3. Make all fields final.
4. Make all fields private
5. Ensure exclusive access to any mutable components
Item 17: Minimize mutability
public final class Invoice {
private final String invoiceNo;
private final Integer total;
private final List<Item> itemList;
public Invoice(String invoiceNo, Integer total, List itemList) {
this.invoiceNo = invoiceNo;
this.total = total;
this.itemList = itemList;
}
public String getInvoiceNo() {
return this.invoiceNo;
}
public Integer getTotal() {
return this.total;
}
public List<Item> getItemList() {
return this.itemList.stream()
.map(Item::clone) // deep copy list elements
.collect(Collectors.toList());
}
}
Make all fields final
Make all fields private
No mutators/setters
Class can't be extended
Ensure exclusive access to any mutable components
Item 17: Minimize mutability
Immutable objects are simple.
Immutable objects are thread-safe
immutable objects can be shared freely.
Exactly one state.
Guarantee invariants.
Require no synchronization
Encourage clients to reuse existing instances wherever possible
Item 17: Minimize mutability
An immutable class can provide static factories (Item 1) that cache frequently
requested instances to avoid creating new instances when existing ones would do.
(Singleton)
public final class A {
private static final A instance1 = new A(...);
private A(...) {
...
}
public static A getInstance1(...) {
return instance1;
}
}
static factory method
cache
Item 17: Minimize mutability
// Immutable class with static factories instead of constructors
public class Complex {
private final double re;
private final double im;
private Complex(double re, double im) {
this.re = re;
this.im = im;
}
public static Complex valueOf(double re, double im) {
return new Complex(re, im);
}
... // Remainder unchanged
}
Flexible immutable class alternative design.
Item 17: Minimize mutability
• You never have to make defensive copies of immutable objects.
• You need not and should not provide a clone method or copy constructor
(Item 13) on an immutable class
• Classes should be immutable unless there’s a very good reason to make
them mutable.
• If a class cannot be made immutable, limit its mutability as much as
possible
• Declare every field private final unless there’s a good reason to do
otherwise.
• The major disadvantage of immutable classes is that they require a separate
object for each distinct value. it is costly. -> Use mutuable companion class
(e.g. String and StringBuilder)
Item 17: Minimize mutability
END
Item 18: Favor composition over
inheritance
Inheriting from ordinary concrete classes across package boundaries is dangerous. Unlike
method invocation, inheritance violates encapsulation.
The superclass’s implementation may change from release
to release, and if it does, the subclass may break, even though its code has not
been touched.
Item 18: Favor composition over
inheritance
// Broken - Inappropriate use of inheritance!
public class InstrumentedHashSet<E> extends HashSet<E> {
// The number of attempted element insertions
private int addCount = 0;
public InstrumentedHashSet() {
}
public InstrumentedHashSet(int initCap, float loadFactor) {
super(initCap, loadFactor);
}
@Override
public boolean add(E e) {
addCount++;
return super.add(e);
}
@Override
public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
}
public int getAddCount() {
return addCount;
}
}
InstrumentedHashSet<String> s = new InstrumentedHashSet<>();
s.addAll(List.of("Snap", "Crackle", "Pop")); // 3 elements
System.out.println(s.getAddCount()); // but print 6
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
The addAll() method in InstrumentedHashSet added
three to addCount and then invoked HashSet’s
addAll() implementation using super.addAll(). This in
turn invoked the add() method, as overridden in
InstrumentedHashSet
Item 18: Favor composition over
inheritance
Instead of extending an existing class, give your new class a private
field that references an instance of the existing class. This design is
called composition because the existing class becomes a component
of the new one.
Item 18: Favor composition over
inheritance
// Wrapper class - uses composition in place of inheritance
public class InstrumentedSet<E> extends ForwardingSet<E> {
private int addCount = 0;
public InstrumentedSet(Set<E> s) {
super(s);
}
@Override public boolean add(E e) {
addCount++;
return super.add(e);
}
@Override public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
}
public int getAddCount() {
return addCount;
}
}
// Reusable forwarding class
public class ForwardingSet<E> implements Set<E> {
private final Set<E> s;
public ForwardingSet(Set<E> s) { this.s = s; }
public void clear() { s.clear(); }
public boolean contains(Object o) { return s.contains(o); }
public boolean isEmpty() { return s.isEmpty(); }
public int size() { return s.size(); }
public Iterator<E> iterator() { return s.iterator(); }
public boolean add(E e) { return s.add(e); }
public boolean remove(Object o) { return s.remove(o); }
public boolean containsAll(Collection<?> c)
{ return s.containsAll(c); }
public boolean addAll(Collection<? extends E> c)
{ return s.addAll(c); }
public boolean removeAll(Collection<?> c)
{ return s.removeAll(c); }
public boolean retainAll(Collection<?> c)
{ return s.retainAll(c); }
public Object[] toArray() { return s.toArray(); }
public <T> T[] toArray(T[] a) { return s.toArray(a); }
@Override public boolean equals(Object o)
{ return s.equals(o); }
@Override public int hashCode() { return s.hashCode(); }
@Override public String toString() { return s.toString(); }
}
composition-and-forwarding approach
Item 18: Favor composition over
inheritance
Decorator pattern
InstrumentedSet
(concrete decorator)
Set
(component)
ForwardingSet
(decorator)
HashSet
(concrete component)
extends
implments
and wrap
implments
Item 18: Favor composition over
inheritance
• Is every B really an A? If you cannot truthfully answer yes to this question, B should
not extend A.
• Does the class that you contemplate extending have any flaws in its API? If so, are
you comfortable propagating those flaws into your class’s API?
Before using inheritance, ask yourself:
Item 18: Favor composition over
inheritance
END
Item 19: Design and document for
inheritance or else prohibit it
The class must document its self-use of overridable methods.
Use Javadoc tag @implSpec to generate description for a method that invokes
overridable methods.
Test your designed for inheritance class by writing subclasses before you release it.
Item 19: Design and document for
inheritance or else prohibit it
Constructors must not invoke overridable methods, directly or indirectly.
public class Super {
// Broken - constructor invokes
an overridable method
public Super() {
overrideMe();
}
public void overrideMe() {
}
}
public final class Sub extends Super {
// Blank final, set by constructor
private final Instant instant;
Sub() {
instant = Instant.now();
}
// Overriding method invoked by
superclass constructor
@Override public void overrideMe() {
System.out.println(instant);
}
}
public static void main(String[] args) {
Sub sub = new Sub(); // null
sub.overrideMe(); // 2020-05-03T08:31:15.449012300Z
}
Item 19: Design and document for
inheritance or else prohibit it
It is generally not a good idea for a class designed for inheritance to implement
Cloneable and Serializable because they place a sub-stantial burden on programmers
who extend the class.
The clone() and readObject() methods behave a lot like constructors, neither clone() nor
readObject() may invoke an overridable method, directly or
indirectly.
In the case of readObject(), the overriding method will run before the subclass’s state
has been deserialized.
In the case of clone(), the overriding method will run before the subclass’s clone()
method has a chance to fix the clone’s state.
Item 19: Design and document for
inheritance or else prohibit it
If you decide to implement Serializable in a class designed for inheritance and the class has
a readResolve() or writeReplace() method, you must
make the readResolve() or writeReplace() method protected rather than private, or they
will be silently ignored by subclasses.
public class InheritableClass implemetns Serializable {
...
protected Object readResolve() throws ObjectStreamException {
....
}
protected Object writeReplace() throws ObjectStreamException {
....
}
}
Item 19: Design and document for
inheritance or else prohibit it
Prohibit subclassing in classes that are not designed and documented to be safely
subclassed.
• Declare the class final.
• Make all constructors private, use factory method instead.
public final class ProhibitExtensionClass {
public ProhibitExtensionClass() {...}
}
public class ProhibitExtensionClass {
private ProhibitExtensionClass() {...}
public static ProhibitExtensionClass createInstance() {
return new ProhibitExtensionClass();
}
}
Item 19: Design and document for
inheritance or else prohibit it
END
Item 20: Prefer interfaces to abstract
classes
Existing classes cannot, in general, be retrofitted to extend a new abstract class.
public class ExsistingClassA extends ExsistingAbstractClass {
@Override
void existingMethod() {...}
@Override
void newMethod() {...}
}
public class ExsistingClassB extends NewAbstractClass {
@Override
void newMethod() {...}
}
public abstract class ExsistingAbstractClass extends NewAbstractClass {
abstract void existingMethod();
}
public abstract class NewAbstractClass {
abstract void newMethod();
}
New abstract class have
to place it high up in the
type hierarchy
Item 20: Prefer interfaces to abstract
classes
Existing classes can easily be retrofitted to implement a new interface
public class ExsistingClassA
extends ExsistingAbstractClass implements NewInterface {
@Override
void existingMethod() {...}
@Override
public void newMethod() {...}
}
public class ExsistingClassB implements NewInterface {
@Override
public void newMethod() {...}
}
public abstract class ExsistingAbstractClass {
abstract void existingMethod();
}
public interface NewInterface {
void newMethod();
}
Item 20: Prefer interfaces to abstract
classes
Interfaces allow for the construction of nonhierarchical type frameworks.
public interface SingerSongwriter extends Singer,
Songwriter {
AudioClip strum();
void actSensitive();
}
public interface Songwriter {
Song compose(int chartPosition);
}
public interface Singer {
AudioClip sing(Song s);
}
Item 20: Prefer interfaces to abstract
classes
• Skeletal implementation class (AbstractInterface)
• e.g. Collections Framework: AbstractCollection, AbstractSet, AbstractList, AbstractMap
• Skeletal implementations are designed for inheritance, good documentation is absolutely essential in a
skeletal implementation (item 19)
• If you export a nontrivial interface, you should strongly consider providing a skeletal implementation to
go with it
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
}
public abstract class AbstractList<E>
extends AbstractCollection<E> implements List<E> {
)
public interface List<E> {
}
Skeletal implementation class
(AbstractInterface)
Item 20: Prefer interfaces to abstract
classes
END
Item 21: Design interfaces for posterity
interface ExistingInterface {
void existingMethod();
default void additionMethod() { // Java 8 default method
// default implementation...
}
}
Java 8 default method allows the addition of methods to exsiting interfaces.
Many new default methods were added to the core collection interfaces in Java 8,
primarily to facilitate the use of lambdas
Item 21: Design interfaces for posterity
Implementation Requirements:
The default method implementations (inherited or otherwise) do not apply any
synchronization protocol. If a Collection implementation has a specific synchronization
protocol, then it must override default implementations to apply that protocol.
org.apache.commons.collections4.collection.SynchronizedCollection implements
Collections
but Java 8 Collections default method removeIf() do not apply any synchronization
protocol
If client call removeIf() method on a SynchronizedCollection instance,
ConcurrentModificationException may result.
Item 21: Design interfaces for posterity
In the presence of default methods, existing implementations of an inter-
face may compile without error or warning but fail at runtime.
Using default methods to add new methods to existing interfaces should be
avoided unless the need is critical
It is still of the utmost importance to design interfaces with great
care.
Item 21: Design interfaces for posterity
END
Item 22: Use interfaces only to define
types
// Constant interface antipattern - do not use!
public interface PhysicalConstants {
// Avogadro's number (1/mol)
static final double AVOGADROS_NUMBER = 6.022_140_857e23;
// Boltzmann constant (J/K)
static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23;
// Mass of the electron (kg)
static final double ELECTRON_MASS = 9.109_383_56e-31;
}
The constant interface pattern is a poor use of interfaces.
• Leak implementation.
• Confuse users.
• Unnecessary commitments
Will these constants be used by all subclasses in the future?
Item 22: Use interfaces only to define
types
END
Item 23: Prefer class hierarchies to
tagged classes
// Class hierarchy replacement for a tagged class
abstract class Figure {
abstract double area();
}
class Circle extends Figure {
final double radius;
Circle(double radius) { this.radius = radius; }
@Override
double area() {
return Math.PI * (radius * radius);
}
}
class Rectangle extends Figure {
final double length;
final double width;
Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
@Override double area() { return length * width; }
}
// Tagged class - vastly inferior to a class hierarchy!
class Figure {
enum Shape { RECTANGLE, CIRCLE };
// Tag field - the shape of this figure
final Shape shape;
// These fields are used only if shape is RECTANGLE
double length;
double width;
// This field is used only if shape is CIRCLE
double radius;
// Constructor for circle
Figure(double radius) {
shape = Shape.CIRCLE;
this.radius = radius;
}
// Constructor for rectangle
Figure(double length, double width) {
shape = Shape.RECTANGLE;
this.length = length;
this.width = width;
}
double area() {
switch(shape) {
case RECTANGLE: return length * width;
case CIRCLE: return Math.PI * (radius * radius);
default: throw new AssertionError(shape);
}
}
}
Item 23: Prefer class hierarchies to
tagged classes
END
Item 24: Favor static member classes
over nonstatic
If a nested class would be useful in some other context, then it should be a top-level
class.
There are four kinds of nested classes:
1. static member classes,
2. nonstatic member classes,
3. anonymous classes,
4. local classes.
If you declare a member class that does not require access to an enclosing
instance, always put the static modifier in its declaration
Item 24: Favor static member classes
over nonstatic
END
Item 25: Limit source files to a single
top-level class
Never put multiple top-level classes or
interfaces in a single source file.
// Two classes defined in one file (Utensil.java). Don't ever do this!
class Utensil {
static final String NAME = "pan";
}
class Dessert {
static final String NAME = "cake";
}
Item 25: Limit source files to a single
top-level class
END

More Related Content

What's hot

Kotlin, 어떻게 동작하나요
Kotlin, 어떻게 동작하나요Kotlin, 어떻게 동작하나요
Kotlin, 어떻게 동작하나요
Chang W. Doh
 
Lec 42.43 - virtual.functions
Lec 42.43 - virtual.functionsLec 42.43 - virtual.functions
Lec 42.43 - virtual.functions
Princess Sam
 
Why we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional Programming
Mario Fusco
 
C# Delegates, Events, Lambda
C# Delegates, Events, LambdaC# Delegates, Events, Lambda
C# Delegates, Events, Lambda
Jussi Pohjolainen
 

What's hot (20)

Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8Pragmatic functional refactoring with java 8
Pragmatic functional refactoring with java 8
 
Wien15 java8
Wien15 java8Wien15 java8
Wien15 java8
 
Lecture 7, c++(complete reference,herbet sheidt)chapter-17.
Lecture 7, c++(complete reference,herbet sheidt)chapter-17.Lecture 7, c++(complete reference,herbet sheidt)chapter-17.
Lecture 7, c++(complete reference,herbet sheidt)chapter-17.
 
Generics in .NET, C++ and Java
Generics in .NET, C++ and JavaGenerics in .NET, C++ and Java
Generics in .NET, C++ and Java
 
Design patterns with Kotlin
Design patterns with KotlinDesign patterns with Kotlin
Design patterns with Kotlin
 
Swift Bengaluru Meetup slides
Swift Bengaluru Meetup slidesSwift Bengaluru Meetup slides
Swift Bengaluru Meetup slides
 
Kotlin, 어떻게 동작하나요
Kotlin, 어떻게 동작하나요Kotlin, 어떻게 동작하나요
Kotlin, 어떻게 동작하나요
 
Lec 42.43 - virtual.functions
Lec 42.43 - virtual.functionsLec 42.43 - virtual.functions
Lec 42.43 - virtual.functions
 
Why we cannot ignore Functional Programming
Why we cannot ignore Functional ProgrammingWhy we cannot ignore Functional Programming
Why we cannot ignore Functional Programming
 
C# Delegates, Events, Lambda
C# Delegates, Events, LambdaC# Delegates, Events, Lambda
C# Delegates, Events, Lambda
 
Java collections framework
Java collections frameworkJava collections framework
Java collections framework
 
SWIFT 3
SWIFT 3SWIFT 3
SWIFT 3
 
Generics
GenericsGenerics
Generics
 
Kotlin
KotlinKotlin
Kotlin
 
Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)
 
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...Map(), flatmap() and reduce() are your new best friends: simpler collections,...
Map(), flatmap() and reduce() are your new best friends: simpler collections,...
 
Java Generics
Java GenericsJava Generics
Java Generics
 
Refactoring to Java 8 (Devoxx BE)
Refactoring to Java 8 (Devoxx BE)Refactoring to Java 8 (Devoxx BE)
Refactoring to Java 8 (Devoxx BE)
 
Java Programming - 03 java control flow
Java Programming - 03 java control flowJava Programming - 03 java control flow
Java Programming - 03 java control flow
 
Virtual function
Virtual functionVirtual function
Virtual function
 

Similar to Effective java-3rd-edition-ch4

Similar to Effective java-3rd-edition-ch4 (20)

Classes & Interfaces
Classes & InterfacesClasses & Interfaces
Classes & Interfaces
 
Java oops PPT
Java oops PPTJava oops PPT
Java oops PPT
 
02-OOP with Java.ppt
02-OOP with Java.ppt02-OOP with Java.ppt
02-OOP with Java.ppt
 
Java Generics
Java GenericsJava Generics
Java Generics
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java
 
Jar chapter 5_part_i
Jar chapter 5_part_iJar chapter 5_part_i
Jar chapter 5_part_i
 
OOPS IN C++
OOPS IN C++OOPS IN C++
OOPS IN C++
 
Lecture 4.2 c++(comlete reference book)
Lecture 4.2 c++(comlete reference book)Lecture 4.2 c++(comlete reference book)
Lecture 4.2 c++(comlete reference book)
 
Structural pattern 3
Structural pattern 3Structural pattern 3
Structural pattern 3
 
Ej Chpt#4 Final
Ej Chpt#4 FinalEj Chpt#4 Final
Ej Chpt#4 Final
 
Java Basic day-2
Java Basic day-2Java Basic day-2
Java Basic day-2
 
Inheritance, polymorphisam, abstract classes and composition)
Inheritance, polymorphisam, abstract classes and composition)Inheritance, polymorphisam, abstract classes and composition)
Inheritance, polymorphisam, abstract classes and composition)
 
7 class objects
7 class objects7 class objects
7 class objects
 
Lecture 2, c++(complete reference,herbet sheidt)chapter-12
Lecture 2, c++(complete reference,herbet sheidt)chapter-12Lecture 2, c++(complete reference,herbet sheidt)chapter-12
Lecture 2, c++(complete reference,herbet sheidt)chapter-12
 
Object Oriented Principle&rsquo;s
Object Oriented Principle&rsquo;sObject Oriented Principle&rsquo;s
Object Oriented Principle&rsquo;s
 
Inheritance.pptx
Inheritance.pptxInheritance.pptx
Inheritance.pptx
 
Java2
Java2Java2
Java2
 
Design pattern
Design patternDesign pattern
Design pattern
 
麻省理工C++公开教学课程(二)
麻省理工C++公开教学课程(二)麻省理工C++公开教学课程(二)
麻省理工C++公开教学课程(二)
 
inhertance c++
inhertance c++inhertance c++
inhertance c++
 

Recently uploaded

Spellings Wk 3 English CAPS CARES Please Practise
Spellings Wk 3 English CAPS CARES Please PractiseSpellings Wk 3 English CAPS CARES Please Practise
Spellings Wk 3 English CAPS CARES Please Practise
AnaAcapella
 
Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdf
ciinovamais
 

Recently uploaded (20)

Towards a code of practice for AI in AT.pptx
Towards a code of practice for AI in AT.pptxTowards a code of practice for AI in AT.pptx
Towards a code of practice for AI in AT.pptx
 
Spellings Wk 3 English CAPS CARES Please Practise
Spellings Wk 3 English CAPS CARES Please PractiseSpellings Wk 3 English CAPS CARES Please Practise
Spellings Wk 3 English CAPS CARES Please Practise
 
Single or Multiple melodic lines structure
Single or Multiple melodic lines structureSingle or Multiple melodic lines structure
Single or Multiple melodic lines structure
 
On National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsOn National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan Fellows
 
ICT Role in 21st Century Education & its Challenges.pptx
ICT Role in 21st Century Education & its Challenges.pptxICT Role in 21st Century Education & its Challenges.pptx
ICT Role in 21st Century Education & its Challenges.pptx
 
Holdier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdfHoldier Curriculum Vitae (April 2024).pdf
Holdier Curriculum Vitae (April 2024).pdf
 
This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.
 
Food safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdfFood safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdf
 
Understanding Accommodations and Modifications
Understanding  Accommodations and ModificationsUnderstanding  Accommodations and Modifications
Understanding Accommodations and Modifications
 
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdfUGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
UGC NET Paper 1 Mathematical Reasoning & Aptitude.pdf
 
ICT role in 21st century education and it's challenges.
ICT role in 21st century education and it's challenges.ICT role in 21st century education and it's challenges.
ICT role in 21st century education and it's challenges.
 
Spatium Project Simulation student brief
Spatium Project Simulation student briefSpatium Project Simulation student brief
Spatium Project Simulation student brief
 
Making communications land - Are they received and understood as intended? we...
Making communications land - Are they received and understood as intended? we...Making communications land - Are they received and understood as intended? we...
Making communications land - Are they received and understood as intended? we...
 
Accessible Digital Futures project (20/03/2024)
Accessible Digital Futures project (20/03/2024)Accessible Digital Futures project (20/03/2024)
Accessible Digital Futures project (20/03/2024)
 
Graduate Outcomes Presentation Slides - English
Graduate Outcomes Presentation Slides - EnglishGraduate Outcomes Presentation Slides - English
Graduate Outcomes Presentation Slides - English
 
Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdf
 
Sociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning ExhibitSociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning Exhibit
 
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
2024-NATIONAL-LEARNING-CAMP-AND-OTHER.pptx
 
Application orientated numerical on hev.ppt
Application orientated numerical on hev.pptApplication orientated numerical on hev.ppt
Application orientated numerical on hev.ppt
 
SOC 101 Demonstration of Learning Presentation
SOC 101 Demonstration of Learning PresentationSOC 101 Demonstration of Learning Presentation
SOC 101 Demonstration of Learning Presentation
 

Effective java-3rd-edition-ch4

  • 1. Effective Java Third Edition Chapter 4 – Classes and Interfaces
  • 2. Item 15: Minimize the accessibility of classes and members Information hiding or encapsulation is important – decouples the components Make each class or member as inaccessible as possible.
  • 3. Item 15: Minimize the accessibility of classes and members If a top-level class or interface can be made package-private, it should be. public class A {...} top-level class class A {...} package-private classs
  • 4. Item 15: Minimize the accessibility of classes and members If class or interface is used by only one class, consider making it a private static nested class of the sole class that uses it. public class A { .... private static class B { ... } } B is ONLY used by A
  • 5. Item 15: Minimize the accessibility of classes and members It is acceptable to make a private member of a public class package-private in order to test it public class A { private void method() {...} } public class A { void method() {...} } Cannot be tested Can be tested by Test Class under the same package
  • 6. Item 15: Minimize the accessibility of classes and members Instance fields of public classes should rarely be public. public class A { public String value1; protected String value2; } public class A { private String value1; private String value2; public String getValue1() { return this.value1; } public String getValue() { return this.value2; } } Not invariants, can be modified by outside or subclass.
  • 7. Item 15: Minimize the accessibility of classes and members It is wrong for a class to have a public static final array field, or an accessor that returns such afield. public class A { public final static Thing[] VALUES = {...}; } public class A { private final static Thing[] VALUES = {...}; public static final Thing[] values() { return VALUES; } } WRONG! Security hole!, public class A { private final static Thing[] PRIVATE_VALUES = {...}; public static final List<Thing> values() { return Collections .unmodifiableList( Arrays.asList(PRIVATE_VALUES)); } public static final Thing[] values() { return PRIVATE_VALUES.clone(); } }
  • 8. Item 15: Minimize the accessibility of classes and members Use Java 9 module system to share classes among packages within a module without making them visible to the entire world.
  • 9. Item 15: Minimize the accessibility of classes and members END
  • 10. Item 16: In public classes, use accessor methods, not public fields class Point { public double x; public double y; } class Point { private double x; private double y; public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public double getY() { return y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } } NO encapsulation!! • if a class is accessible outside its package (public class), provide accessor methods. • public classes should never expose mutable fields.
  • 11. Item 16: In public classes, use accessor methods, not public fields class A { ... private class B { public int value; } } class A { int value; } if a class is package-private or is a private nested class, there is nothing inherently wrong with exposing its data fields private nested class package-private class
  • 12. Item 16: In public classes, use accessor methods, not public fields END
  • 13. Item 17: Minimize mutability How to make a immutable class: 1. Don’t provide methods that modify the object’s state (No mutators/setters) 2. Ensure that the class can’t be extended. 3. Make all fields final. 4. Make all fields private 5. Ensure exclusive access to any mutable components
  • 14. Item 17: Minimize mutability public final class Invoice { private final String invoiceNo; private final Integer total; private final List<Item> itemList; public Invoice(String invoiceNo, Integer total, List itemList) { this.invoiceNo = invoiceNo; this.total = total; this.itemList = itemList; } public String getInvoiceNo() { return this.invoiceNo; } public Integer getTotal() { return this.total; } public List<Item> getItemList() { return this.itemList.stream() .map(Item::clone) // deep copy list elements .collect(Collectors.toList()); } } Make all fields final Make all fields private No mutators/setters Class can't be extended Ensure exclusive access to any mutable components
  • 15. Item 17: Minimize mutability Immutable objects are simple. Immutable objects are thread-safe immutable objects can be shared freely. Exactly one state. Guarantee invariants. Require no synchronization Encourage clients to reuse existing instances wherever possible
  • 16. Item 17: Minimize mutability An immutable class can provide static factories (Item 1) that cache frequently requested instances to avoid creating new instances when existing ones would do. (Singleton) public final class A { private static final A instance1 = new A(...); private A(...) { ... } public static A getInstance1(...) { return instance1; } } static factory method cache
  • 17. Item 17: Minimize mutability // Immutable class with static factories instead of constructors public class Complex { private final double re; private final double im; private Complex(double re, double im) { this.re = re; this.im = im; } public static Complex valueOf(double re, double im) { return new Complex(re, im); } ... // Remainder unchanged } Flexible immutable class alternative design.
  • 18. Item 17: Minimize mutability • You never have to make defensive copies of immutable objects. • You need not and should not provide a clone method or copy constructor (Item 13) on an immutable class • Classes should be immutable unless there’s a very good reason to make them mutable. • If a class cannot be made immutable, limit its mutability as much as possible • Declare every field private final unless there’s a good reason to do otherwise. • The major disadvantage of immutable classes is that they require a separate object for each distinct value. it is costly. -> Use mutuable companion class (e.g. String and StringBuilder)
  • 19. Item 17: Minimize mutability END
  • 20. Item 18: Favor composition over inheritance Inheriting from ordinary concrete classes across package boundaries is dangerous. Unlike method invocation, inheritance violates encapsulation. The superclass’s implementation may change from release to release, and if it does, the subclass may break, even though its code has not been touched.
  • 21. Item 18: Favor composition over inheritance // Broken - Inappropriate use of inheritance! public class InstrumentedHashSet<E> extends HashSet<E> { // The number of attempted element insertions private int addCount = 0; public InstrumentedHashSet() { } public InstrumentedHashSet(int initCap, float loadFactor) { super(initCap, loadFactor); } @Override public boolean add(E e) { addCount++; return super.add(e); } @Override public boolean addAll(Collection<? extends E> c) { addCount += c.size(); return super.addAll(c); } public int getAddCount() { return addCount; } } InstrumentedHashSet<String> s = new InstrumentedHashSet<>(); s.addAll(List.of("Snap", "Crackle", "Pop")); // 3 elements System.out.println(s.getAddCount()); // but print 6 public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) if (add(e)) modified = true; return modified; } The addAll() method in InstrumentedHashSet added three to addCount and then invoked HashSet’s addAll() implementation using super.addAll(). This in turn invoked the add() method, as overridden in InstrumentedHashSet
  • 22. Item 18: Favor composition over inheritance Instead of extending an existing class, give your new class a private field that references an instance of the existing class. This design is called composition because the existing class becomes a component of the new one.
  • 23. Item 18: Favor composition over inheritance // Wrapper class - uses composition in place of inheritance public class InstrumentedSet<E> extends ForwardingSet<E> { private int addCount = 0; public InstrumentedSet(Set<E> s) { super(s); } @Override public boolean add(E e) { addCount++; return super.add(e); } @Override public boolean addAll(Collection<? extends E> c) { addCount += c.size(); return super.addAll(c); } public int getAddCount() { return addCount; } } // Reusable forwarding class public class ForwardingSet<E> implements Set<E> { private final Set<E> s; public ForwardingSet(Set<E> s) { this.s = s; } public void clear() { s.clear(); } public boolean contains(Object o) { return s.contains(o); } public boolean isEmpty() { return s.isEmpty(); } public int size() { return s.size(); } public Iterator<E> iterator() { return s.iterator(); } public boolean add(E e) { return s.add(e); } public boolean remove(Object o) { return s.remove(o); } public boolean containsAll(Collection<?> c) { return s.containsAll(c); } public boolean addAll(Collection<? extends E> c) { return s.addAll(c); } public boolean removeAll(Collection<?> c) { return s.removeAll(c); } public boolean retainAll(Collection<?> c) { return s.retainAll(c); } public Object[] toArray() { return s.toArray(); } public <T> T[] toArray(T[] a) { return s.toArray(a); } @Override public boolean equals(Object o) { return s.equals(o); } @Override public int hashCode() { return s.hashCode(); } @Override public String toString() { return s.toString(); } } composition-and-forwarding approach
  • 24. Item 18: Favor composition over inheritance Decorator pattern InstrumentedSet (concrete decorator) Set (component) ForwardingSet (decorator) HashSet (concrete component) extends implments and wrap implments
  • 25. Item 18: Favor composition over inheritance • Is every B really an A? If you cannot truthfully answer yes to this question, B should not extend A. • Does the class that you contemplate extending have any flaws in its API? If so, are you comfortable propagating those flaws into your class’s API? Before using inheritance, ask yourself:
  • 26. Item 18: Favor composition over inheritance END
  • 27. Item 19: Design and document for inheritance or else prohibit it The class must document its self-use of overridable methods. Use Javadoc tag @implSpec to generate description for a method that invokes overridable methods. Test your designed for inheritance class by writing subclasses before you release it.
  • 28. Item 19: Design and document for inheritance or else prohibit it Constructors must not invoke overridable methods, directly or indirectly. public class Super { // Broken - constructor invokes an overridable method public Super() { overrideMe(); } public void overrideMe() { } } public final class Sub extends Super { // Blank final, set by constructor private final Instant instant; Sub() { instant = Instant.now(); } // Overriding method invoked by superclass constructor @Override public void overrideMe() { System.out.println(instant); } } public static void main(String[] args) { Sub sub = new Sub(); // null sub.overrideMe(); // 2020-05-03T08:31:15.449012300Z }
  • 29. Item 19: Design and document for inheritance or else prohibit it It is generally not a good idea for a class designed for inheritance to implement Cloneable and Serializable because they place a sub-stantial burden on programmers who extend the class. The clone() and readObject() methods behave a lot like constructors, neither clone() nor readObject() may invoke an overridable method, directly or indirectly. In the case of readObject(), the overriding method will run before the subclass’s state has been deserialized. In the case of clone(), the overriding method will run before the subclass’s clone() method has a chance to fix the clone’s state.
  • 30. Item 19: Design and document for inheritance or else prohibit it If you decide to implement Serializable in a class designed for inheritance and the class has a readResolve() or writeReplace() method, you must make the readResolve() or writeReplace() method protected rather than private, or they will be silently ignored by subclasses. public class InheritableClass implemetns Serializable { ... protected Object readResolve() throws ObjectStreamException { .... } protected Object writeReplace() throws ObjectStreamException { .... } }
  • 31. Item 19: Design and document for inheritance or else prohibit it Prohibit subclassing in classes that are not designed and documented to be safely subclassed. • Declare the class final. • Make all constructors private, use factory method instead. public final class ProhibitExtensionClass { public ProhibitExtensionClass() {...} } public class ProhibitExtensionClass { private ProhibitExtensionClass() {...} public static ProhibitExtensionClass createInstance() { return new ProhibitExtensionClass(); } }
  • 32. Item 19: Design and document for inheritance or else prohibit it END
  • 33. Item 20: Prefer interfaces to abstract classes Existing classes cannot, in general, be retrofitted to extend a new abstract class. public class ExsistingClassA extends ExsistingAbstractClass { @Override void existingMethod() {...} @Override void newMethod() {...} } public class ExsistingClassB extends NewAbstractClass { @Override void newMethod() {...} } public abstract class ExsistingAbstractClass extends NewAbstractClass { abstract void existingMethod(); } public abstract class NewAbstractClass { abstract void newMethod(); } New abstract class have to place it high up in the type hierarchy
  • 34. Item 20: Prefer interfaces to abstract classes Existing classes can easily be retrofitted to implement a new interface public class ExsistingClassA extends ExsistingAbstractClass implements NewInterface { @Override void existingMethod() {...} @Override public void newMethod() {...} } public class ExsistingClassB implements NewInterface { @Override public void newMethod() {...} } public abstract class ExsistingAbstractClass { abstract void existingMethod(); } public interface NewInterface { void newMethod(); }
  • 35. Item 20: Prefer interfaces to abstract classes Interfaces allow for the construction of nonhierarchical type frameworks. public interface SingerSongwriter extends Singer, Songwriter { AudioClip strum(); void actSensitive(); } public interface Songwriter { Song compose(int chartPosition); } public interface Singer { AudioClip sing(Song s); }
  • 36. Item 20: Prefer interfaces to abstract classes • Skeletal implementation class (AbstractInterface) • e.g. Collections Framework: AbstractCollection, AbstractSet, AbstractList, AbstractMap • Skeletal implementations are designed for inheritance, good documentation is absolutely essential in a skeletal implementation (item 19) • If you export a nontrivial interface, you should strongly consider providing a skeletal implementation to go with it public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { } public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { ) public interface List<E> { } Skeletal implementation class (AbstractInterface)
  • 37. Item 20: Prefer interfaces to abstract classes END
  • 38. Item 21: Design interfaces for posterity interface ExistingInterface { void existingMethod(); default void additionMethod() { // Java 8 default method // default implementation... } } Java 8 default method allows the addition of methods to exsiting interfaces. Many new default methods were added to the core collection interfaces in Java 8, primarily to facilitate the use of lambdas
  • 39. Item 21: Design interfaces for posterity Implementation Requirements: The default method implementations (inherited or otherwise) do not apply any synchronization protocol. If a Collection implementation has a specific synchronization protocol, then it must override default implementations to apply that protocol. org.apache.commons.collections4.collection.SynchronizedCollection implements Collections but Java 8 Collections default method removeIf() do not apply any synchronization protocol If client call removeIf() method on a SynchronizedCollection instance, ConcurrentModificationException may result.
  • 40. Item 21: Design interfaces for posterity In the presence of default methods, existing implementations of an inter- face may compile without error or warning but fail at runtime. Using default methods to add new methods to existing interfaces should be avoided unless the need is critical It is still of the utmost importance to design interfaces with great care.
  • 41. Item 21: Design interfaces for posterity END
  • 42. Item 22: Use interfaces only to define types // Constant interface antipattern - do not use! public interface PhysicalConstants { // Avogadro's number (1/mol) static final double AVOGADROS_NUMBER = 6.022_140_857e23; // Boltzmann constant (J/K) static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23; // Mass of the electron (kg) static final double ELECTRON_MASS = 9.109_383_56e-31; } The constant interface pattern is a poor use of interfaces. • Leak implementation. • Confuse users. • Unnecessary commitments Will these constants be used by all subclasses in the future?
  • 43. Item 22: Use interfaces only to define types END
  • 44. Item 23: Prefer class hierarchies to tagged classes // Class hierarchy replacement for a tagged class abstract class Figure { abstract double area(); } class Circle extends Figure { final double radius; Circle(double radius) { this.radius = radius; } @Override double area() { return Math.PI * (radius * radius); } } class Rectangle extends Figure { final double length; final double width; Rectangle(double length, double width) { this.length = length; this.width = width; } @Override double area() { return length * width; } } // Tagged class - vastly inferior to a class hierarchy! class Figure { enum Shape { RECTANGLE, CIRCLE }; // Tag field - the shape of this figure final Shape shape; // These fields are used only if shape is RECTANGLE double length; double width; // This field is used only if shape is CIRCLE double radius; // Constructor for circle Figure(double radius) { shape = Shape.CIRCLE; this.radius = radius; } // Constructor for rectangle Figure(double length, double width) { shape = Shape.RECTANGLE; this.length = length; this.width = width; } double area() { switch(shape) { case RECTANGLE: return length * width; case CIRCLE: return Math.PI * (radius * radius); default: throw new AssertionError(shape); } } }
  • 45. Item 23: Prefer class hierarchies to tagged classes END
  • 46. Item 24: Favor static member classes over nonstatic If a nested class would be useful in some other context, then it should be a top-level class. There are four kinds of nested classes: 1. static member classes, 2. nonstatic member classes, 3. anonymous classes, 4. local classes. If you declare a member class that does not require access to an enclosing instance, always put the static modifier in its declaration
  • 47. Item 24: Favor static member classes over nonstatic END
  • 48. Item 25: Limit source files to a single top-level class Never put multiple top-level classes or interfaces in a single source file. // Two classes defined in one file (Utensil.java). Don't ever do this! class Utensil { static final String NAME = "pan"; } class Dessert { static final String NAME = "cake"; }
  • 49. Item 25: Limit source files to a single top-level class END