热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CoreJavaVolumeI—Fundamentals(3)

Chapter6Interfaces,LambdaExpressions,andInnerClasses6.1.1TheInterfaceConceptAninterfa
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 implement keyword 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 instanceOf to 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 compare method 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 protected method of Object, which means that your code cannot simply call it. A subclass can call a protected clone method 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 clone method to make a deep copy that clones the subobjects as well.

For every class, you need to decide whether

    1. The default clone method is good enough;
    2. The default clone method can be patched up by calling clone on the mutable subobjects; and
    3. clone should not be attempted

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

    1. Implement the Cloneable interface; and
    2. 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 implements Cloneable { ... public Sample clone() throws CloneNotSupportedException { // Call Object.clone()
    Sample clOned= (Sample) super.clone(); //Clone mutable fields
    cloned.hireDay = (Date) hireDay.clone(); return cloned; } }

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 ObjectObject is not a functional interface.

          Predicate (in the java.util.function):

public interface Predicate { boolean test(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 , super parameter 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 stream library solves that problem with constructor references.

Pass ClassName ::new to the toArray method:

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

The toArray method 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:

    1. A block of code
    2. Parameters
    3. 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 this keyword 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.

Anonymous inner 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 

new SuperType(construction parameters)
    {
    inner class methods 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. SuperType can 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:

new InterfaceType()
    {
    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 static and 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 handler is an object of any class that implements the InvovationHandler interface. The interface has a single method:

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

Whenever a method is called on the proxy object, the invoke method 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 Class objects, 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 Proxy class in Oracle’s virtual machine generates class names that begin with the string $Proxy.

If you call the newProxyInstance method 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 public and 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.


推荐阅读
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • Python实现变声器功能(萝莉音御姐音)的方法及步骤
    本文介绍了使用Python实现变声器功能(萝莉音御姐音)的方法及步骤。首先登录百度AL开发平台,选择语音合成,创建应用并填写应用信息,获取Appid、API Key和Secret Key。然后安装pythonsdk,可以通过pip install baidu-aip或python setup.py install进行安装。最后,书写代码实现变声器功能,使用AipSpeech库进行语音合成,可以设置音量等参数。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
  • 本文介绍了Java中Currency类的getInstance()方法,该方法用于检索给定货币代码的该货币的实例。文章详细解释了方法的语法、参数、返回值和异常,并提供了一个示例程序来说明该方法的工作原理。 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
author-avatar
js陈富军中草药
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有