core java volume i--fundamentals_Core Java Volume I—Fundamentals (3)

Chapter 6 Interfaces, Lambda Expressions, and Inner Classes

6.1.1 The Interface Concept

An interface is a set of requirements for the classes that wan to conform to the interface.

All methods of an interface are automatically public.

Interfaces never have instance fields.

Use implementkeyword to declare a class implements an interface.

Caution:

When implementing the interface, you must declare the method as public.

6.1.2 Properties of Interfaces

You can declare interface variables.

An interface variable must refer to an object of a class that implements the interface.

You can use instanceOfto check whether an object implements an interface:

if (anObject instanceOf Comparable) {…}

You can extend interfaces. This allows for multiple chains of interfaces that go form a greater degree of generality to a greater degree of specification.

You cannot put static methods in interfaces, however you can supply constants in them which are always public static final.

Use commas(,) to separate the interfaces that you want to implement.

6.1.3 Interfaces and Abstract Classes

A class can only extend a single class.

6.1.4 Static Methods

As of Java SE8, you can add static methods to interfaces.

6.1.5 Default Methods

You can supply a default implementation for any interface method. You must tag such a method with the default method modifier.

As of Java SE8, you can declare all of the methods as default methods that do nothing.

A default method can call other methods.

An important use for default methods is interface evolution.

Adding a method to an interface is binary compatible.

/*

binary compatible: a property of computer systems meaning that they can run the same executable code, typically machine code for a general-purpose computer CPU. (without recompilation)

source compatible: recompilation or interpretation is necessary.

*/

6.2 Examples of Interfaces

6.2.1 Interfaces and Callbacks

In the callback pattern, you specify the action that should occur whenever a particular event happens.

Passing an object is more flexible than passing a function because the object can carry additional information.

6.2.2 Comparator Interface

String.compareTo method compares strings in dictionary order.

To compare strings by length, define a class that implements Comarator.

The comparemethod is called on the comparator (an instance of a class that implements the Comparator interface) object, not the string itself.

6.2.3 Object Cloning

A change to either variable also affects the other if the original and the copy are references to the same object.

The clone method is a protectedmethod of Object,which means that your code cannot simply call it. A subclass can call a protected clonemethod only to clone its own objects. You must redefine clone method to be public to allow objects to be cloned by any method.

The default cloning operation is “shallow”—it does not clone objects that are referenced inside other objects. If the subobject shared between the original and the shallow clone is immutable, then the sharing is safe.

However, quite frequently, the subobjects are mutable, and you must redefine the clonemethod to make a deep copythat clones the subobjects as well.

For every class, you need to decide whether

The default clone method is good enough;

The default clonemethod can be patched up by calling cloneon the mutable subobjects; and

cloneshould not be attempted

To choose either the first or the second option, a class must

Implement the Cloneable interface; and

Redefine the clone method with the public access modifier

The Cloneable interface merely serves as a tag, indicating that the class designer understands the cloning process.

You need to implement the Cloneable interface, redefine clone to be public, and call super.clone().

To make a deep copy, you have to clone the mutable instance field.

Example:

class Sample implementsCloneable

{

...public Sample clone() throwsCloneNotSupportedException

{//Call Object.clone()

Sample cloned = (Sample) super.clone();//Clone mutable fields

cloned.hireDay =(Date) hireDay.clone();returncloned;

}

}

6.3 Lambda Expressions

6.3.1 Why Lambdas?

A lambda expression is a block of code that you can pass around so that it can be executed later, once or multiple times.

6.3.2 The Syntax of Lambda Expressions

One form of lambda expressions in Java: parameters, the -> arrow, and an expression, enclosed in {} and with explicit return statements:

(DataType firstParam, DataType secondParam) ->{

…return…;

}

If a lambda expression has no parameters, you still supply empty parentheses, just as with a parameterless method:

() -> { … ;}

If the parameter types of a lambda expression can be inferred, you can omit them.

//example

Comparator comp = (first, second) //same as (String first, String second)

-> first.length() – second.length();

If a method has a single parameter with inferred type, you can even omit the parentheses:

ActionListener listener = event -> …;  //instead of (event) -> … or (ActionListener event) -> …

You never specify the result type of a lambda expression. It is always inferred from the context.

It is illegal for a lambda expression to return a value in some branches but not in others.

6.3.3 Functional Interfaces

You can supply a lambda expression whenever an object of an interface with a single abstract method is expected.

A functional interface must have a single abstract method.

It is best to think of a lambda expression as function, not an object, and to accept that it can be passed to a functional interface.

In fact, conversion to a functional interface is the only thing that you can do with a lambda expression in Java.

You cannot assign a lambda expression to a variable of type Object–Object is not a functional interface.

Predicate(in the java.util.function):

public interface Predicate{booleantest(T t);//Additional default and static methods

}

The ArrayList class has a removeIf method whose parameter is a Predicate. It’s specifically designed to pass a lambda expression.

//example

List.removeIf(e-> e == null) //removes all null values from an array list

6.3.4 Method References

The :: operator separates the method name from the name of an object or class. There are 3 principle cases:

object::instanceMethod

Class::staticMethod

Class::instanceMethod

In the first 2 cases, the method reference is equivalent to a lambda expression that supplies parameters of the method.

In the third case, the first parameter becomes the target of the method.

You can capture the this, superparameter in a method reference.

Example

this::function is the same as x -> this.function(x)

The method expression

super::instanceMethod

uses this as the target and invokes the superclass version of the given method.

6.3.5 Constructor Reference

ClassName::new is a reference to a ClassName constructor.

You can form a constructor references with array types. Array constructor references overcome a limitation that you cannot construct an array of a generic type T. The expression new T[]is an error since it would be erased  to new Object[n]. The streamlibrary solves that problem with constructor references.

Pass ClassName ::new to the toArray method:

ClassName objectVar = stream.toArray(ClassName[] ::new);

The toArraymethod invokes this constructor to obtain an array of the correct type. Then it fills and returns the array.

6.3.6 Variable Scope

A lambda expression has three ingredients:

A block of code

Parameters

Values for the free variables, that is, the variables that are not parameters and not defined inside the code.

Closure: a block of code together with the values of the free variables.

A lambda expression can capture the value of a variable in the enclosing scope.

In a lambda expression, you can only reference variables whose value doesn’t change.

Any captured variable in a lambda expression must be effectively final. An effectively final variable is a variable that is never assigned a new value after it has been initialized.

The body of a lambda expression has the same scope as a nested block. It’s illegal to declare a parameter or a local variable in the lambda that has the same name as a local variable.

When you use thiskeyword in a lambda expression, you refer to the this parameter of the method that creates the lambda.

6.3.7 Processing Lambda Expressions

The point of using lambda expression is deferred execution.

If you design your own interface with a single abstract method, you can tag it with the @FunctionalInterface annotation.

The Comparator interface has a number of convenient static methods for creating comparators. These methods are intended to be used with lambda expressions or method references.

Examples:

//sort by name

Arrays.sort(people, Comparator.comparing(Person::getName));//sort by length

Arrays.sort(people, Comparator.comparing(Person::getName),(s, t) -> Integer.compare(s.length(), t.length()));

6.4 Inner Classes

An inner class is a class that is defined inside another class.

Inner class method can access the data from the scope in which they are defined—including the data that would otherwise be private.

Inner classes can be hidden from other classes in the same package.

Anonymousinner classes are handy when you want to define callbacks without writing a lot of code.

/*

A callback is any executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at a given time.

*/

6.4.1 Use of an Inner Class to Access Object State

An inner class method gets to access both its own data fields and those of the outer object creating it. An object of an inner class always gets an implicit reference to the object that created it. The outer class reference is set in the constructor. The compiler modifies all inner class constructors, adding a parameter for the outer class reference.

Only inner class can be private. Regular classes always have either package or public visibility.

Any static fields declared in an inner class must be final.

6.4.4 Local inner Classes

If you need the name of the type only once when you create an object of that type, you can define the class locally in a single method.

Local classes are never declared with an access specifier (public or private). Their scope is always restricted to the block in which they are declared.

One great advantage—local classes are completely hidden from the outside world.

6.4.5 Accessing Variables from Outer Methods

Local classes can access local variables which are effectively final.

6.4.6 Anonymous Inner Class

If you want to make a single object of the class, you don’t need to give the class a name. Such a class is called an anonymous inner class.

In general, the syntax is

newSuperType(construction parameters)

{

innerclassmethods with data

}

6.4.6 Anonymous Inner Class

If you want to make a single object of the class, you don’t need to give the class a name. Such a class is called an anonymous inner class.

In general, the syntax is

Here SuperType can be an interface; then the inner class implements that interface.SuperTypecan also be a class; then, the inner class extends that class.

An anonymous inner class cannot have constructors. Instead, the construction parameters are given to the superclass constructor. Particularly, whenever an inner class implements an interface, it cannot have any construction parameter.

Syntax:

newInterfaceType()

{

methods of data;

}

Double Brace Initialization:suppose you want to

construct an array list and pass it to a method, then you don’t need it again

and make it anonymous, how to add elements?

sampleMethod(new ArrayList() {{add(“Sample-1”); add(“Sample-2”);}});

The outer {} makes an anonymous subclass of ArrayList.The inner {} is an object construction block.

new Object(){}

makes an anonymous object of an anonymous subclass of Object.

6.4.7 Static Inner Class

By declaring the inner class static, you can suppress the generation of the reference to the outer class object.

Only inner classes can be declared static.

Use a static inner class whenever the inner class does not need to access an outer class object.

Static inner classes can have static fields and methods.

Inner classes that are declared inside an interface are automatically staticand public.

6.5 Proxies

6.5.1 When to Use Proxies

Suppose you want to construct an object of a class that implements one or more interface whose exact nature you may not know at compile time. You need to define a new class in a running program.

The proxy class has the following methods:

All the methods required by the specified interfaces; and

All methods defined in the Object class (toString, equals, and so on)

You cannot define new code for these methods at runtime unless you supply an invocation handler.

An invocation handleris an object of any class that implements the InvovationHandlerinterface. The interface has a single method:

Object invoke(Object proxy, Method method, Object[] args)

Whenever a method is called on the proxy object, the invokemethod of the invocation handler gets called, with the Method object and parameters of the original call. The invocation handler must then figure out how to handle the call.

6.5.2 Creating Proxy Objects

To create a proxy object, use the newProxyInstance method of the Proxy class. The method has three parameters:

A class loader, for now, we specify null to use the default class loader.

An array of Classobjects, one for each interface to be implemented.

An invocation handler

Proxies can be used for purposes such as

Routing method calls to remote servers

Tracing method calls for debugging purposes

Associating user interface events with actions in a running program

6.5.3 Properties of Proxy Classes

All proxy classes extend the class Proxy.

All proxy classes override the toString, equals, and hashCode methods of the Object class.

The name of proxy classes are not defined. The Proxyclass in Oracle’s virtual machine generates class names that begin with the string $Proxy.

If you call the newProxyInstancemethod twice with the same class loader and interface array, you get 2 objects of the same class. You can also obtain that class with the getProxyClass method:

Class proxyClass = Proxy.getProxyClass(null, interfaces);

A proxy class is always publicand final. All non-public interfaces must belong to the same package, and the proxy class will also belong to that package.

By calling the isProxyClass method of the Proxy class, you can test whether a particular Class object represents a proxy class.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Core Java Volume I–Fundamentals, 1 (11th Edition) By 作者: Cay S. Horstmann ISBN-10 书号: 0135166306 ISBN-13 书号: 9780135166307 Edition 版本: 11 出版日期: 2018-09-06 pages 页数: 928 The #1 Java Guide for Serious Programmers: Fully Updated for Java SE 9, 10 & 11 For serious programmers, Core Java, Volume I—Fundamentals, Eleventh Edition, is the definitive guide to writing robust, maintainable code. Whether you’re using Java SE 9, 10, or 11, it will help you achieve a deep and practical understanding of the language and API, and its hundreds of realistic examples reveal the most powerful and effective ways to get the job done. Cay Horstmann’s updated examples reflect Java’s long-awaited modularization, showing how to write code that’s easier to manage and evolve. You’ll learn how to use JShell’s new Read-Eval-Print Loop (REPL) for more rapid and exploratory development, and apply key improvements to the Process API, contended locking, logging, and compilation. In this first of two volumes, Horstmann offers in-depth coverage of fundamental Java and UI programming, including objects, generics, collections, lambda expressions, Swing design, concurrency, and functional programming. If you’re an experienced programmer moving to Java SE 9, 10, or 11, there’s no better source for expert insight, solutions, and code. Master foundational techniques, idioms, and best practices for writing superior Java code Leverage the power of interfaces, lambda expressions, and inner classes Harden programs through effective exception handling and debugging Write safer, more reusable code with generic programming Improve performance and efficiency with Java’s standard collections Build cross-platform GUIs with the Swing toolkit Fully utilize multicore processors with Java’s improved concurrency

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值