Item 1: Consider static factory methods instead of constructors
- Static factory method ?
Advantages - Unlike constructors, they have names - Unlike constructors, they are not required to create a new object each time they're invoked - Unlike constructors, they can return an object of any subtype of their return type - They reduce the verbosity of creating parameterized type instances
Disadvantages - Classes without public or protected constructors cannot be subclassed - They are not readily distinguishable from other static methods
Summary Static factories and public constructors both have merits but often static factories are preferable. Hence, it pays to put a thought before next time creating a public or protected constructor.
[Effective Java][Item 1]Consider static factory methods instead of constructorsOmkar Shetkar2017-03-22 | Creating and Destroying Objects
Item 1: Consider static factory methods instead of constructors
- Static factory method ?
Advantages - Unlike constructors, they have names - Unlike constructors, they are not required to create a new object each time they're invoked - Unlike constructors, they can return an object of any subtype of their return type - They reduce the verbosity of creating parameterized type instances
Disadvantages - Classes without public or protected constructors cannot be subclassed - They are not readily distinguishable from other static methods
Summary Static factories and public constructors both have merits but often static factories are preferable. Hence, it pays to put a thought before next time creating a public or protected constructor.Java Enums EssentialsOmkar Shetkar2023-01-19 | Essential features of Java Enums
👉 GitHub: github.com/Omkar-Shetkar/java-labsEffective Java | Item 44 | Favor the use of standard functional interfacesOmkar Shetkar2022-11-27 | * If one of the standard functional interfaces does the job, you should generally use it in preference to a purpose-built functional interface. * Don't be tempted to use basic functional interfaces with boxed primitives instead of primitive functional interfaces. * You should prefer to write custom functional interface in preference to using a standard one only if * It will be commonly used and could benefit from a descriptive name. * It has a strong contract associated with it. * It would benefit from custom default methods. * Always annotate your functional interfaces with the @FunctionalInterface annotation. * Do not provide a method with multiple overloadings that take different functional interfaces in the same argument position if it could create a possible ambiguity in the client.
GitHub: github.com/Omkar-Shetkar/effective-javaEffective Java | Item 43 | Prefer method references to lambdasOmkar Shetkar2022-11-20 | - Creating function objects even with less verbose code as compared to lambdas - Method reference variances - Static - Bound - Unbound - Class Constructor - Array Constructor
GitHub: github.com/Omkar-Shetkar/effective-javaEffective Java | Item 42 | Prefer lambdas to anonymous classesOmkar Shetkar2022-11-14 | From Java 1.1, function objects were created using anonymous classes They were verbose and hence unappealing Come Java 8, replace anonymous classes with lambda expressions Lambdas implement interfaces with single abstract method, which are known as functional interfaces Lambdas are concise and less verbose
Chrome: chrome.google.com/webstore/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm?hl=enEffective Java | Item 54 | Return empty collections or arrays, not nullsOmkar Shetkar2022-02-20 | Item 54: Return empty collections or arrays, not nulls - Returning null for empty collections or arrays, makes the API consumption very difficult and error prone. - It has no performance gains. github.com/Omkar-Shetkar/effective-javaEffective Java | Item 53 | Use varargs judiciouslyOmkar Shetkar2022-02-20 | Item 53: Use varargs judiciously - varargs are useful in methods where we expect variable number of arguments - methods which expect atleast one or more arguments, needs special attention while using varargs - varargs have slight impact on performance. Hence, while designing methods with varargs, take judicious decision on frequent method calls with number of arguments.Effective Java | Item 52 | Use overloading judiciouslyOmkar Shetkar2022-02-08 | Item 52: Use overloading judiciously
The choice of which overloading to invoke is made at compile time Selection among overloaded methods is static, while selection among overridden methods is dynamic. Avoid confusing uses of overloading A safe and conservative approach is never to have two overloadings with the same number of parameters. You can always give methods different names instead of overloading them. Constructors can't be overridden. Multiple constructors can always be overloaded. Multiple overloadings with the same number of parameters should not confuse the programmer, if it is always clear which overloading will apply for the given set of actual parameters. This will be true if at least one parameter in the two overloaded methods of same number of parameters, is radically of different type. Generics and autoboxing have increased the need for caution during overloading. Two distinct classes are said to be unrelated, if neither class is descendant of the other. If overloading two methods with similar arguments is unavoidable, then ensure that both of the methods have identical behavior when invoked.
- Choose method names carefully - Consistent with other names in the package - Consistent with the broader consensus
- Don't go overboard in providing convenience methods - Every method should "pull its weight" - Each action supported by class should have corresponding method - Consider providing "shorthand" only if it will be used often. When in doubt, leave it out.
- Avoid long parameter lists - Aim for max of 4 or less than 4 parameters - To avoid long sequence of identically typed parameters - Break the method up into multiple methods, each of which requires only a subset of the parameters. - Create helper classes to hold groups of parameters. - Adapt the Builder pattern from object construction to method invocation.
- For parameter types, favor interfaces over classes
- Prefer two-element enum types to boolean parameters
Github: github.com/Omkar-Shetkar/effective-javaEffective Java | Item 39 | Make defensive copies when neededOmkar Shetkar2020-10-04 | If a class is accepting or returning mutable components, then it should consider defensive copy of these components. If copy is costly and class trusts its clients then defensive copy may be replaced by documentation outlining the client's repsonsibility not to modify the affected components.Effective Java | Item 38 | Check parameters for validityOmkar Shetkar2020-09-12 | Each time you write a method or constructor, you should think about what restrictions exist on its parameters. You should document these restrictions and enforce them with explicit checks at the beginning of the method body.[Effective Java] [Item 65] Dont ignore exceptionsOmkar Shetkar2020-08-30 | ...[Effective Java] [Item 64] Strive for failure atomicityOmkar Shetkar2020-08-30 | ...[Effective Java] [Item 63] Include failure-capture information in detail messagesOmkar Shetkar2020-08-30 | ...[Effective Java] [Item 62] Document all exceptions thrown by each methodOmkar Shetkar2020-08-30 | ...[Effective Java] [Item 61] Throw exceptions appropriate to the abstractionOmkar Shetkar2020-08-30 | ...[Effective Java][Item 59-60] When to use checked and unchecked exceptions ? [contd...]Omkar Shetkar2020-08-22 | Item 59: Avoid unnecessary use of checked exceptions Item 60: Favor the use of standard exceptions[Effective Java] [Item 58] When to use checked and runtime exceptions ?Omkar Shetkar2020-08-16 | Use checked exceptions for recoverable conditions and runtime exceptions for programming errors.
- Immutable objects are always reusable. - Prefer reuse of an object rather creating new functionally equivalent object - Don't create String with new operator - Prefer using static factory methods over constructors for creating instances of immutable classes - Its better to cache expensive objects - Prefer primitives to boxed primitives, and watch out for unintentional autoboxing - This item should NOT be misunderstood that "object creation is expensive and should be avoided" - Its okay to create short lived and lightweight objects, since modern garbage collectors are efficient - Avoiding creating unnecessary objects is only a matter of style and performance concern - Many times creating new object is more secure than reusing an object Moral of the story: Take a conscious decision while creating an object Can I reuse it or create a new one ?[Effective Java] [Item 5] Prefer dependency injection to hardwiring resourcesOmkar Shetkar2019-04-09 | github.com/Omkar-Shetkar/effective-java
Creating and Destroying Objects
Item 5: Prefer dependency injection to hardwiring resources
- Inappropriate approaches - Use of static utility classes - Use of singletons - Static utility classes and singletons are inappropriate for classes whose behavior is parameterized by an underlying resource
- Dependency Injection approaches - pass the resource into the constructor when creating a new instance - DI is equally applicable to constructors, static factories, and builders - pass a resource factory to the constructor
- Advantages of DI approaches - greatly improves flexibility, reusability, and testability
- Disdvantages of DI approaches - it can clutter up large projects, which typically contain thousands of dependencies - solution is to use DI frameworkds such as Dagger, Guice, or Spring[Effective Java] [Item 4] Enforce noninstantiability with a private constructorOmkar Shetkar2019-03-23 | Creating and Destroying Objects
Item 4: Enforce noninstantiability with a private constructor
- Occasionally we want to have a class that is just a grouping of static mehtods and static fields - Used to group related methods on primitive values or arrays Eg., java.lang.Math or java.util.Arrays - Used to group static methods, including factory methods, for objects that implement a particular interface Eg., java.util.Collections - Used to group methods on a final class, instead of extending the class
- Attempting to enforce noninstantiability by making a class abstract does not work.
- A class can be made noninstantiable by including a private constructor. - As a side effect, this idiom also prevents the class from being subclassed.[Effective Java] [Item 3] Enforce the singleton property with a private constructor or an enum typeOmkar Shetkar2019-03-18 | Creating and Destroying Objects
Item 3: Enforce the singleton property with a private constructor or an enum type
- A singleton is simply a class that is instantiated exactly once. - Making a class a singleton can make it difficult to test its clients
- Before release 1.5, there were two ways to implement singletons: 1. public member is a final field - the lack of public or protected constructor guarantees unique object Advantages: - public static final field makes it clear that it is singleton 2. public member is a static factory method - public static factory method can be changed without affecting clients
- Enum singleton - the preferred approach - it is more concise - provides the serialization machinery for free - provides ironclad guarantee against multiple instantiation
- A Single-element enum type is the best way to implement a singleton.[Effective Java] [Item 2] Consider a builder when faced with many constructor parametersOmkar Shetkar2019-02-20 | - Telescoping constructor pattern - does not scale well! - unreadable, prone to hard to debug errors
- JavaBeans pattern - allows inconsistency, mandates mutability - invariance cannot be maintained - maintaining thread safety of the class difficult
- Builder pattern - safe and readable - Parameter validation can be done while object construction - Can have multiple varargs parameters - Builder pattern is flexible - Builder whose parameters have been set makes a fine Abstract Factory
Disadvantages - Creating a builder object may be costly in some performance critical situations - It is more verbose than telescoping constructor pattern
Summary - Builder pattern is a good choice when designing classes whose constructors or static factories would have more than a handful of parameters[Effective Java] [Item 45] Minimize the scope of local variablesOmkar Shetkar2018-06-18 | - What is Scope ?
- Why to minimize the scope of variables ? - Unintended results and debugging such bugs is difficult - Readability for other developers - "Programs are meant to be read by humans and only incidentally for computers to execute"
- How to minimize scope ? - Declare variable where it is used - Ugly exception to this rule is when initializing method throws exception - Control structures such as loops help - Prefere for loops to while loops - Keep methods small and focused[Effective Java][Item 66] Synchronize access to shared mutable dataOmkar Shetkar2017-06-12 | Item 66 : Synchronize access to shared mutable data
Why synchronization? - Mutual exclusion - Transfer of data between threads - Liveness failure - Java memory model - happens-before relationship - Safety failure - use volatile primitives with caution - prefer Atomic object types to primitive types
- Prefer immutable objects - Avoid mutable object sharing - Prefer to mutability confined to single thread before publishing to the world[Effective Java] IntroductionOmkar Shetkar2017-03-17 | Introduction to "Effective Java", 3rd Edition ~ Joshua Bloch.How to download youtube videos from command line ?Omkar Shetkar2017-02-15 | youtube-dl is a command line tool to download videos from many sites including youtube. It has tens of options to download single, multiple, playlists with different resolutions etc.