仿制药名言_仿制药的美丽与陌生

仿制药名言

最近,我正在为Oracle认证专家Java SE 7程序员考试做准备,而我恰巧在Java泛型领域遇到了一些看起来很奇怪的构造。 但是,我也看到了一些巧妙而优雅的代码。 我发现这些示例值得分享,这不仅是因为它们可以使您的设计选择更加容易,并且使代码更加健壮和可重用,而且还因为其中的某些示例在您不习惯泛型时非常棘手。 我决定将这篇文章分为四个章节,这些章节几乎反映了我在学习和工作经历中对仿制药的经验。

您了解泛型吗?

当我们四处看看时,可以发现泛型在Java Universe的许多不同框架中都大量使用。 它们从Web应用程序框架到Java本身的集合。 由于这个话题已经在我之前被很多人解释过了,所以我将只列出我认为有价值的资源,然后转到有时根本没有提及或解释得不好的东西(通常在网上发布的注释或文章中) 。 因此,如果您不了解核心泛型概念,则可以查看以下一些材料:

  • Katherine Sierra和Bert Bates的SCJP Sun认证Java 6考试程序员
    • 对我而言,本书的主要目的是为参加Oracle提供的OCP考试做好准备。
  • 课程: Oracle的泛型(已更新)
    • 资源由Oracle本身提供。
  • Maurice Naftalin和Philip Wadler的Java泛型和集合
    • O'Reilly Media制作的另一本很棒的Java书籍。

泛型不允许做什么?

假设您了解泛型,并希望了解更多信息,那么请转到无法完成的工作。 令人惊讶的是,有很多东西无法与泛型一起使用。 在使用泛型时,我选择了以下六个避免陷阱的示例。

类型为<T>静态字段

许多没有经验的程序员常犯的一个常见错误是试图声明静态成员。 在下面的示例中可以看到,任何尝试都会导致编译器错误,如下所示: Cannot make a static reference to the non-static type T

public class StaticMember<T> {// causes compiler errorstatic T member;
}

类型为<T>实例

另一个错误是尝试通过在泛型类型上调用new来实例化任何类型。 这样,编译器将导致错误提示: Cannot instantiate the type T

public class GenericInstance<T> {public GenericInstance() {// causes compiler errornew T();}
}

与原始类型不兼容

使用泛型时最大的限制之一似乎是它们与原始类型不兼容。 的确,您不能在声明中直接使用基元,但是,可以用适当的包装器类型替换基元,然后就可以了。 整个情况在以下示例中呈现:

public class Primitives<T> {public final List<T> list = new ArrayList<>();public static void main(String[] args) {final int i = 1;// causes compiler error// final Primitives<int> prim = new Primitives<>();final Primitives<Integer> prim = new Primitives<>();prim.list.add(i);}
}

在编译期间, Primitives类的第一个实例化将失败,并出现与以下错误类似的错误: Syntax error on token "int", Dimensions expected after this token 。 使用包装器类型和少量自动装箱魔术可绕过此限制。

<T>类型的数组

使用泛型的另一个明显限制是无法实例化泛型类型的数组。 考虑到数组对象的基本特征,原因很明显–它们在运行时保留其类型信息。 如果违反了它们的运行时类型完整性,则运行时异常ArrayStoreException可以挽救这一天。

public class GenericArray<T> {// this one is finepublic T[] notYetInstantiatedArray;// causes compiler errorpublic T[] array = new T[5];
}

但是,如果尝试直接实例化一个通用数组,则将出现如下编译错误: Cannot create a generic array of T

通用异常类

有时,程序员可能需要传递泛型类型的实例以及引发异常。 这在Java中是不可能的。 下面的示例描述了这种努力。

// causes compiler error
public class GenericException<T> extends Exception {}

当您尝试创建这样的异常时,您将得到如下消息: The generic class GenericException<T> may not subclass java.lang.Throwable

关键字superextends替代含义

值得一提的最后一个限制,特别是对于新手来说,是泛型时关键字superextends的替代含义。 为了生成利用泛型的精心设计的代码,了解这一点非常有用。

  • <? extends T>
    • 含义:通配符是指扩展类型T和类型T本身的任何类型。
  • <? super T>
    • 含义:通配符是指T的任何超类型以及T本身。

一点点的美

关于Java我最喜欢的事情之一是它的强类型。 众所周知,泛型是在Java 5中引入的,它们被用来使我们更容易使用集合(它们不仅在集合中被用于更多领域,但这是设计阶段泛型的核心论点之一) 。 即使泛型仅提供编译时保护,并且不输入字节码,但它们提供了相当有效的方式来确保类型安全。 以下示例显示了泛型的一些不错的功能或用例。

泛型适用于类和接口

这可能一点都不令人惊讶,但是是的-接口和泛型是兼容的构造。 尽管将泛型与接口结合使用非常普遍,但我发现这一事实实际上是非常酷的功能。 这使程序员可以在考虑类型安全和代码重用的情况下创建甚至更高效的代码。 例如,考虑以下来自包java.lang接口Comparable示例:

public interface Comparable<T> {public int compareTo(T o);
}

泛型的简单介绍使得有可能从compareTo方法中省略check实例,从而使代码更具凝聚力并提高了可读性。 通常,泛型有助于使代码更易于阅读和理解,并有助于引入类型顺序。

泛型允许优雅使用范围

关于限制通配符,有一个很好的例子说明了在库类Collections可以实现的目标。 此类声明方法copy ,该方法在以下示例中定义,并使用有界通配符来确保列表的复制操作的类型安全。

public static <T> void copy(List<? super T> dest, List<? extends T> src) { ... }

让我们仔细看看。 方法copy被声明为返回void的静态泛型方法。 它接受两个参数-目标和源(并且两者都是有界的)。 目标必须存储仅属于TT类型本身的超类型的类型。 另一方面,源必定仅由T类型的扩展类型或T类型本身构成。 这两个约束保证了集合和复制操作都保持类型安全。 我们不需要使用数组,因为它们通过抛出上述ArrayStoreException异常防止了任何类型安全冲突。

泛型支持多边界

不难想象为什么人们会只使用一种简单的边界条件而不是使用更多的条件。 实际上,这样做很容易。 考虑以下示例:我需要创建一个接受参数的方法,该参数既是Comparable也是数字List 。 开发人员将被迫创建不必要的接口ComparableList,以便在通用时间内履行上述合同。

public class BoundsTest {interface ComparableList extends List, Comparable {}class MyList implements ComparableList { ... }public static void doStuff(final ComparableList comparableList) {}public static void main(final String[] args) {BoundsTest.doStuff(new BoundsTest().new MyList());}
}

在执行此任务之后,我们可以忽略这些限制。 使用泛型可以使我们创建满足所需合同的具体类,但使doStuff方法尽可能开放。 我发现的唯一缺点是语法相当冗长。 但是,由于它仍然保持很好的可读性和易于理解性,因此我可以忽略此缺陷。

public class BoundsTest {class MyList<T> implements List<T>, Comparable<T> { ... }public static <T, U extends List<T> & Comparable<T>> void doStuff(final U comparableList) {}public static void main(final String[] args) {BoundsTest.doStuff(new BoundsTest().new MyList<String>());}
}

有点奇怪

我决定为这篇文章的最后一章专门介绍到目前为止我遇到的两种最奇怪的构造或行为。 您极有可能永远不会遇到这样的代码,但是我发现提到它很有趣。 因此,事不宜迟,让我们见识这些奇怪的东西。

尴尬的代码

与任何其他语言构造一样,您可能最终会遇到一些看起来很奇怪的代码。 我想知道最奇怪的代码是什么样的,以及它是否甚至可以通过编译。 我能想到的最好的是下面的代码。 您可以猜测该代码是否可以编译?

public class AwkwardCode<T> {public static <T> T T(T T) {return T;}
}

即使这是一个非常糟糕的编码示例,也可以成功编译,并且应用程序可以正常运行。 第一行声明泛型类AwkwardCode ,第二行声明泛型方法T 方法T是返回T实例的通用方法。 它采用T类型的参数,不幸的是称为T 该参数也会在方法主体中返回。

通用方法调用

最后一个示例显示了与泛型结合使用时类型推断的工作原理。 当我看到一段代码不包含方法调用的通用签名却声称要通过编译时,我偶然发现了这个问题。 当某人对泛型只有很少的经验时,这样的代码可能一见钟情。 您能否解释以下代码的行为?

public class GenericMethodInvocation {public static void main(final String[] args) {// 1. returns trueSystem.out.println(Compare.<String> genericCompare("1", "1"));// 2. compilation errorSystem.out.println(Compare.<String> genericCompare("1", new Long(1)));// 3. returns falseSystem.out.println(Compare.genericCompare("1", new Long(1)));}
}class Compare {public static <T> boolean genericCompare(final T object1, final T object2) {System.out.println("Inside generic");return object1.equals(object2);}
}

好吧,让我们分解一下。 第一次调用genericCompare非常简单。 我表示参数类型将是什么类型的方法,并提供该类型的两个对象-此处没有奥秘。 由于Long不是StringgenericCompare第二次调用无法编译。 最后,对genericCompare第三次调用返回false 。 这很奇怪,因为该方法被声明为接受相同类型的两个参数,但是最好将其传递给String文字和Long对象。 这是由编译期间执行的类型擦除过程引起的。 由于方法调用未使用泛型的<String>语法,因此编译器无法告诉您要传递两种不同的类型。 始终记住,最接近的共享继承类型用于查找匹配的方法声明。 意思是,当genericCompare接受object1object2 ,它们被genericCompare转换为Object ,但由于运行时多态性而被比较为StringLong实例–因此该方法返回false 。 现在让我们修改一下代码。

public class GenericMethodInvocation {public static void main(final String[] args) {// 1. returns trueSystem.out.println(Compare.<String> genericCompare("1", "1"));// 2. compilation errorSystem.out.println(Compare.<String> genericCompare("1", new Long(1)));// 3. returns falseSystem.out.println(Compare.genericCompare("1", new Long(1)));// compilation errorCompare.<? extends Number> randomMethod();// runs fineCompare.<Number> randomMethod();}
}class Compare {public static <T> boolean genericCompare(final T object1, final T object2) {System.out.println("Inside generic");return object1.equals(object2);}public static boolean genericCompare(final String object1, final Long object2) {System.out.println("Inside non-generic");return object1.equals(object2);}public static void randomMethod() {}
}

此新代码示例通过添加genericCompare方法的非泛型版本并定义一个不执行任何操作并从GenericMethodInvocation类的main方法调用两次的新randomMethod来修改Compare类。 由于我提供了与给定调用匹配的新方法,因此该代码使对genericCompare的第二次调用genericCompare可能。 但这引发了一个关于另一个奇怪行为的问题–第二个呼叫是否通用? 事实证明–不,不是。 但是,仍然可以使用泛型的<String>语法。 为了更清楚地展示此功能,我使用此通用语法创建了对randomMethod新调用。 再次由于类型擦除过程而实现了这一点-擦除了这种通用语法。

但是,当有界通配符出现在舞台上时,这种情况会改变。 编译器以编译器错误的形式向我们发送清晰的消息,说: Wildcard is not allowed at this location ,这使得无法编译代码。 要编译和运行代码,必须注释掉第12行。以这种方式修改代码后,它将产生以下输出:

Inside generic
true
Inside non-generic
false
Inside non-generic
false

翻译自: https://www.javacodegeeks.com/2014/06/beauty-and-strangeness-of-generics.html

仿制药名言

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/341692.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何区分光猫、路由器和交换机?

如今&#xff0c;网络已经进入了千家万户&#xff0c;上网已成为了我们生活中必不可少的事情。通常&#xff0c;在家里最常见的网络设备有&#xff1a;光猫&#xff08;光调制解调器&#xff09;、路由器、交换机&#xff0c;但很多小白用户并不能轻易区分它们。当遇上网络故障…

Java 12:开关表达式

在Java 12中&#xff0c;对switch语句进行了增强&#xff0c;以便可以将其用作表达式。 现在也可以在一种情况下打开多个常量&#xff0c;从而使代码更简洁易读。 这些增强是预览语言功能 &#xff0c;这意味着必须使用--enable-preview标志在Java编译器和运行时中显式启用它们…

什么是网络延长器?

网络延长器就是能够把网络传输距离有效延长的设备&#xff0c;网络延长器能够突破传统以太网传输距离100米以内的限制&#xff0c;可以通过双绞线将100M网络传输500米&#xff0c;10M网络传输1500米甚至更长。它将网络的传输距离的极限从铜线的100米扩展到千米以上&#xff0c;…

什么是延长器?延长器常见类型介绍

延长器是用来延长信号的器件&#xff0c;通常用于长距离直连线材无法满足传输要求的情况&#xff0c;一般是为了确保信号长距离无衰减的传输而设计&#xff0c;因此多是有源的。那么&#xff0c;什么是延长器&#xff1f;延长器的常见类型有哪些呢&#xff1f;接下来我们就一起…

solr 模糊匹配_Solr中的前缀和后缀匹配

solr 模糊匹配搜索引擎都是关于查找字符串的。 用户输入一个查询词&#xff0c;然后从反向索引中检索它。 有时&#xff0c;用户正在寻找的值只是索引中值的子字符串&#xff0c;并且用户可能也对这些匹配感兴趣。 对于德语这样的包含复合词&#xff08;如Semmelkndel&#xff…

视频编解码器常见问题介绍

视频编解码器&#xff0c;是指一个能够对数字视频进行压缩或者解压缩的程序或者设备。通常这种压缩属于有损数据压缩。历史上&#xff0c;视频信号是以模拟形式存储在磁带上的。那么&#xff0c;我们在使用视频编解码器的过程中遇到的一些常见问题有哪些呢&#xff1f;接下来我…

Java中的双重检查锁定

在本文中&#xff0c;我们将介绍在RxJava中创建Singleton对象的一些技术。 最重要的是&#xff0c;我们将学习Java中的双重检查锁定 。 Java中的Singleton模式是一种创新模式。 随着时间的流逝&#xff0c;人们开始关注Singleton模式的使用和实现。 这是由于单例的实现和使用方…

视频干扰的原因及解决方法

我们在视频监控和视频传输会议中常常会遇到视频信号被干扰的困扰&#xff0c;由于视频干扰产生画面抖动、显示模糊等显示问题&#xff0c;严重影响使用效果。那么这些干扰信号时如何产生的&#xff0c;又该如何解决呢&#xff1f;接下来我们就跟随飞畅科技的小编一起来详细了解…

网络监控系统安装的4种方式,安防必备

现如今&#xff0c;随着人们安防意识的提高&#xff0c;监控从业人员也越来越多。对于刚刚加入这个行业的新人来讲&#xff0c;可能首先要从最基层的监控设备安装做起。只有在实践中不断积累经验技术&#xff0c;才有可能独当一面、快速成长。作为一名新手&#xff0c;网络监控…

it编年史_Java的编年史和低延迟

it编年史总览 我正在看Typesafe的Rolan Kuhn在介绍React流方面的精彩演讲&#xff0c;乍一看似乎与《纪事报》有一些相似的目标&#xff0c;但是当您深入研究细节时&#xff0c;很明显我有一些关键的假设根本不同。 关键假设 《纪事》设计的主要假设是 低延迟是您的问题&#…

智慧磐石工程项目系统组成

武警部队智慧磐石工程以五防一体化建设为基础&#xff0c;融入各类前沿智能检测、识别、控制等相关技术&#xff0c;通过整合指挥、监控、防护、报警、通信、处置要素&#xff0c;实现信息智能管理、环境智能分析、通道智能防范、监控智能识别、险情智能感知、枪弹智能管控、情…

网络延长器分为哪几类?其应用领域有哪些?

网络延长器具有超低传输时延&#xff0c;能够线速转发数据包。网络延长器采用自主产权的LRE&#xff08;Long- Reacher Ethernet&#xff09;长线以太网驱动技术&#xff0c;能有效延长以太网传输距离达700米&#xff0c;同时保障最大传输带宽。基本原理是通过信号整形放大&…

Java项目:书评

本文是关于这本书的 Peter Verhas撰写的Java Projects Second Edition 我去年写的 这样一篇文章的目的通常是为了促进这本书的销售。 在这种情况下没有什么不同&#xff0c;但是由于这是我写的书&#xff0c;而且我是撰写评论的人&#xff0c;因此赞美这本书将非常尴尬。 所以…

信号延长器常见故障问题及解决方案汇总

延长器是用来延长信号的器件&#xff0c;通常用于长距离直连线材无法满足传输要求的情况&#xff0c;一般是为了确保信号长距离无衰减的传输而设计&#xff0c;因此多是有源的。我们在使用信号延长器的过程中难免会遇到各种各样的故障问题&#xff0c;那么我们该如何解决呢&…

一文读懂视频监控系统全过程内容

视频监控系统由实时控制系统、监视系统及管理信息系统组成。视频监控系统是安全防范系统的组成部分&#xff0c;它是一种防范能力较强的综合系统。视频监控以其直观、方便、信息内容丰富而广泛应用于许多场合。接下来就由飞畅科技来为大家详细介绍下视频监控系统的全过程&#…

以太网识别标准及接线标准、接线方法详解

以太网是目前应用最普遍的局域网技术&#xff0c;取代了其他局域网技术如令牌环、FDDI和ARCNET。为了使网络系统中的软硬件设备不受生产厂家和型号等不同的限制&#xff0c;制定了各种各样的标准来保证他们之间的相互通&#xff0c;以太网标准就是其中之一&#xff0c;IEEE组织…

Spring Framework中的作用域代理

Spring框架提供了Spring bean的作用域。 我们可以使用spring范围控制插入Spring bean的各种依赖关系和配置值。 Spring支持以下六个范围。 在基于Web的应用程序中可以使用六个中的四个&#xff1a; 范围 描述 辛格尔顿 它是Spring框架中的默认范围。 对于每个Spring IOC容…

中继器、集线器、网桥、网关产品介绍

在了解通信原理之前&#xff0c;我们首先要对通信常用的设备进行熟悉&#xff0c;计算机网络体系中&#xff0c;有几样通信设备或者说网络名词出现的频率相当高&#xff0c;它们是&#xff1a;中继器、集线器、网桥、交换机、路由器和网关。其实&#xff0c;弄清楚这几个计算机…

串口转换器的工作方式及通讯模式介绍

串口转换器能让您在配有RS-232的系统上使用RS-422及RS-485。它透明地将RS-232信号转成隔离的RS-422或RS-485信号。对此&#xff0c;您无需改变PC机任何的硬件或软件就能让您利用标准的PC硬件&#xff0c;来轻松构建一个工业级的长距离通信系统&#xff1b;基于TCP/IP和RS-485/4…

java8根据某个id删选_Java 8可选:如何使用它

java8根据某个id删选Java 8带有新的Optional类型&#xff0c;类似于其他语言中可用的类型。 这篇文章将介绍这种新类型的使用方式&#xff0c;即主要用途。 什么是可选类型&#xff1f; 可选的是新容器类型&#xff0c;如果有可用值&#xff0c;则该容器类型将包装单个值。 因…