<解惑>jvm如何理解java零基础入门书籍泛型类

IBM Setting generic JVM arguments in WebSphere Application Server - United States
Setting generic JVM arguments in WebSphere Application Server
Java Virtual M J SDK; JDK; Xoptions
Technote (troubleshooting)
Problem(Abstract)
This technote explains where one can set generic Java(TM) Virtual Machine (JVM) arguments in the administration console for WebSphere Application Server.
Resolving the problem
The generic JVM arguments are used to configure and adjust how the JVM executes. Once changes are made and saved to the master configuration, the JVM requires a restart for the arguments to take effect.
NOTE: Setting JVM arguments on the WebSphere Application Server Liberty has different steps.
Each JVM argument is separated by a space. This is also called it's delimiter.
For example, if presented with these two JVM arguments to add to an already full list of arguments: -Xrs -Xint
You would apply each argument individually, separating each with a space.
[other arguments] -Xrs -Xint [other arguments]
NOTE: WebSphere Application Server Liberty has
Application Server
In the Administration Console select Servers
Expand Server Type and select WebSphere application servers
Click on the name of your server
Expand Java and Process Management and select Process Definition.
Under the Additional Properties section, click Java Virtual Machine.
Scroll down and locate the textbox for Generic JVM arguments.
In the Administration Console, select System Administration
Select Node agents
Choose which nodeagent to edit
In the Server Infrastructure section, expand Java and Process Management and select Process Definition.
Under the Additional Properties section, click Java Virtual Machine.
Scroll down and locate the textbox for Generic JVM arguments.
Deployment Manager
In the Administration Console, select System Administration
Select Deployment manager
In the Server Infrastructure section, expand Java and Process Management and select Process Definition.
Under the Additional Properties section, click Java Virtual Machine.
Scroll down and locate the textbox for Generic JVM arguments.
Application Server
In the Administration Console select Servers
Expand Server Type and select WebSphere application servers
Click on the name of your server
Expand Java and Process Management and select Process Definition.
Under the Additional Properties section, click Java Virtual Machine.
Scroll down and locate the textbox for Generic JVM arguments.
In the Administration Console, select System Administration
Select Node agents
Choose which nodeagent to edit
In the Server Infrastructure section, expand Java and Process Management and select Process Definition.
Under the Additional Properties section, click Java Virtual Machine.
Scroll down and locate the textbox for Generic JVM arguments.
Deployment Manager
In the Administration Console, select System Administration
Select Deployment manager
In the Server Infrastructure section, expand Java and Process Management and select Process Definition.
Under the Additional Properties section, click Java Virtual Machine.
Scroll down and locate the textbox for Generic JVM arguments.
Related information
Document information
More support for:
Administrative Console (all non-scripting)
Software version:
7.0, 8.0, 8.5, 8.5.5, 9.0
Operating system(s):
AIX, HP-UX, Linux, Solaris, Windows
Software edition:
Base, Express, Network Deployment
Reference #:
Modified date:
13 January 2010
Translate this page:
Contact and feedback
Need support?
1-800-IBM-7378 (USA)Java泛型详解 - Robin99 - 博客园
泛型(Generic type 或者generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。&可以在集合框架(Collection framework)中看到泛型的动机。例如,Map类允许您向一个Map添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如String)的对象。&因为Map.get()被定义为返回Object,所以一般必须将Map.get()的结果强制类型转换为期望的类型,如下面的代码所示:&Map m = new HashMap();&m.put("key", "blarg");&String s = (String) m.get("key");&要让程序通过编译,必须将get()的结果强制类型转换为String,并且希望结果真的是一个String。但是有可能某人已经在该映射中保存了不是String的东西,这样的话,上面的代码将会抛出ClassCastException。&理想情况下,您可能会得出这样一个观点,即m是一个Map,它将String键映射到String值。这可以让您消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的键或值保存在集合中。这就是泛型所做的工作。&泛型的好处&Java 语言中引入泛型是一个较大的功能增强。不仅语言、类型系统和编译器有了较大的变化,以支持泛型,而且类库也进行了大翻修,所以许多重要的类,比如集合框架,都已经成为泛型化的了。这带来了很多好处:&· 类型安全。泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。&Java 程序中的一种流行技术是定义这样的集合,即它的元素或键是公共类型的,比如“String列表”或者“String到String的映射”。通过在变量声明中捕获这一附加的类型信息,泛型允许编译器实施这些附加的类型约束。类型错误现在就可以在编译时被捕获了,而不是在运行时当作ClassCastException展示出来。将类型检查从运行时挪到编译时有助于您更容易找到错误,并可提高程序的可靠性。&· 消除强制类型转换。泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。&尽管减少强制类型转换可以降低使用泛型类的代码的罗嗦程度,但是声明泛型变量会带来相应的罗嗦。比较下面两个代码例子。&该代码不使用泛型:&List li = new ArrayList();&li.put(new Integer(3));&Integer i = (Integer) li.get(0);&该代码使用泛型:&List&Integer& li = new ArrayList&Integer&();&li.put(new Integer(3));&Integer i = li.get(0);&在简单的程序中使用一次泛型变量不会降低罗嗦程度。但是对于多次使用泛型变量的大型程序来说,则可以累积起来降低罗嗦程度。&· 潜在的性能收益。泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的JVM 的优化带来可能。&由于泛型的实现方式,支持泛型(几乎)不需要JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。&泛型用法的例子&泛型的许多最佳例子都来自集合框架,因为泛型让您在保存在集合中的元素上指定类型约束。考虑这个使用Map类的例子,其中涉及一定程度的优化,即Map.get()返回的结果将确实是一个String:&Map m = new HashMap();&m.put("key", "blarg");&String s = (String) m.get("key");&如果有人已经在映射中放置了不是String的其他东西,上面的代码将会抛出ClassCastException。泛型允许您表达这样的类型约束,即m是一个将String键映射到String值的Map。这可以消除代码中的强制类型转换,同时获得一个附加的类型检查层,这个检查层可以防止有人将错误类型的键或值保存在集合中。&下面的代码示例展示了 JDK 5.0 中集合框架中的Map接口的定义的一部分:&public interface Map&K, V& {&public void put(K key, V value);&public V get(K key);&}&注意该接口的两个附加物:&* 类型参数 K 和 V 在类级别的规格说明,表示在声明一个 Map 类型的变量时指定的类型的占位符。&* 在 get()、put() 和其他方法的方法签名中使用的 K 和 V。&为了赢得使用泛型的好处,必须在定义或实例化Map类型的变量时为K和V提供具体的值。以一种相对直观的方式做这件事:&Map&String, String& m = new HashMap&String, String&();&m.put("key", "blarg");&String s = m.get("key");&当使用Map的泛型化版本时,您不再需要将Map.get()的结果强制类型转换为String,因为编译器知道get()将返回一个String。&在使用泛型的版本中并没有减少键盘录入;实际上,比使用强制类型转换的版本需要做更多键入。使用泛型只是带来了附加的类型安全。因为编译器知道关于您将放进Map中的键和值的类型的更多信息,所以类型检查从执行时挪到了编译时,这会提高可靠性并加快开发速度。&向后兼容&在 Java 语言中引入泛型的一个重要目标就是维护向后兼容。尽管 JDK 5.0 的标准类库中的许多类,比如集合框架,都已经泛型化了,但是使用集合类(比如HashMap和ArrayList)的现有代码将继续不加修改地在 JDK 5.0 中工作。当然,没有利用泛型的现有代码将不会赢得泛型的类型安全好处。&类型参数&在定义泛型类或声明泛型类的变量时,使用尖括号来指定形式类型参数。形式类型参数与实际类型参数之间的关系类似于形式方法参数与实际方法参数之间的关系,只是类型参数表示类型,而不是表示值。&泛型类中的类型参数几乎可以用于任何可以使用类名的地方。例如,下面是java.util.Map接口的定义的摘录:&public interface Map&K, V& {&public void put(K key, V value);&public V get(K key);&}&Map接口是由两个类型参数化的,这两个类型是键类型K和值类型V。(不使用泛型)将会接受或返回Object的方法现在在它们的方法签名中使用K或V,指示附加的类型约束位于Map的规格说明之下。&当声明或者实例化一个泛型的对象时,必须指定类型参数的值:&Map&String, String& map = new HashMap&String, String&();&注意,在本例中,必须指定两次类型参数。一次是在声明变量map的类型时,另一次是在选择HashMap类的参数化以便可以实例化正确类型的一个实例时。&编译器在遇到一个Map&String, String&类型的变量时,知道K和V现在被绑定为String,因此它知道在这样的变量上调用Map.get()将会得到String类型。&除了异常类型、枚举或匿名内部类以外,任何类都可以具有类型参数。&命名类型参数&推荐的命名约定是使用大写的单个字母名称作为类型参数。这与C++ 约定有所不同(参阅附录 A:与 C++ 模板的比较),并反映了大多数泛型类将具有少量类型参数的假定。对于常见的泛型模式,推荐的名称是:&* K —— 键,比如映射的键。&* V —— 值,比如 List 和 Set 的内容,或者 Map 中的值。&* E —— 异常类。&* T —— 泛型。&泛型不是协变的&关于泛型的混淆,一个常见的来源就是假设它们像数组一样是协变的。其实它们不是协变的。List&Object&不是List&String&的父类型。&如果 A 扩展 B,那么 A 的数组也是 B 的数组,并且完全可以在需要B[]的地方使用A[]:&Integer[] intArray = new Integer[10];&Number[] numberArray = intA&上面的代码是有效的,因为一个Integer是一个Number,因而一个Integer数组是一个Number数组。但是对于泛型来说则不然。下面的代码是无效的:&List&Integer& intList = new ArrayList&Integer&();&List&Number& numberList = intL // invalid&最初,大多数 Java 程序员觉得这缺少协变很烦人,或者甚至是“坏的(broken)”,但是之所以这样有一个很好的原因。如果可以将List&Integer&赋给List&Number&,下面的代码就会违背泛型应该提供的类型安全:&List&Integer& intList = new ArrayList&Integer&();&List&Number& numberList = intL // invalid&numberList.add(new Float(3.1415));&因为intList和numberList都是有别名的,如果允许的话,上面的代码就会让您将不是Integers的东西放进intList中。但是,正如下一屏将会看到的,您有一个更加灵活的方式来定义泛型。&package com.ibm.course.&import java.util.ArrayL&import java.util.L&public class GenericsExample {&public static void main(String[] args) {&Integer[] integer = new Integer[5];&Number[] number =&System.out.println(number[0]);// null&number[0] = new Float(7.65);&System.out.println(number[0]);&System.out.println(integer[0]);&List&Integer& list = new ArrayList&Integer&();&// Type mismatch: cannot convert from List&Integer& to List&Number&&// List&Number& listObj =&}&}&List&Number& listObj =导致编译错误:Type mismatch: cannot convert from List&Integer& to List&Number&&而System.out.println(number[0]);和System.out.println(integer[0]);导致运行时异常:&Exception in thread "main" java.lang.ArrayStoreException: java.lang.Float&at com.ibm.course.generics.GenericsExample.main(GenericsExample.java:15)&类型通配符&假设您具有该方法:&void printList(List l) {&for (Object o : l)&System.out.println(o);&}&上面的代码在 JDK 5.0 上编译通过,但是如果试图用List&Integer&调用它,则会得到警告。出现警告是因为,您将泛型(List&Integer&)传递给一个只承诺将它当作List(所谓的原始类型)的方法,这将破坏使用泛型的类型安全。&如果试图编写像下面这样的方法,那么将会怎么样?&void printList(List&Object& l) {&for (Object o : l)&System.out.println(o);&}&它仍然不会通过编译,因为一个List&Integer&不是一个List&Object&(正如前一屏泛型不是协变的 中所学的)。这才真正烦人——现在您的泛型版本还没有普通的非泛型版本有用!&解决方案是使用类型通配符:&void printList(List&?& l) {&for (Object o : l)&System.out.println(o);&}&上面代码中的问号是一个类型通配符。它读作“问号”。List&?&是任何泛型List的父类型,所以您完全可以将List&Object&、List&Integer&或List&List&List&Flutzpah&&&传递给printList()。&package com.ibm.course.&import java.util.ArrayL&import java.util.L&public class GenericExample {&public static void main(String[] args) {&List&Integer& integer = new ArrayList&Integer&();&integer.add(new Integer(0));&integer.add(new Integer(1));&List&String& str = new ArrayList&String&();&str.add(new String("Hello"));&str.add(new String("World"));&List&?& li=&li=&printList(integer);&printList(str);&}&public static void printList(List&?& l) {&for (Object o : l) {&System.out.println(o);&}&}&}&上面的例子程序没有警告也没有编译错误。&类型通配符的作用&前一屏类型通配符 中引入了类型通配符,这让您可以声明List&?&类型的变量。您可以对这样的List做什么呢?非常方便,可以从中检索元素,但是不能添加元素(可以添加null)。原因不是编译器知道哪些方法修改列表哪些方法不修改列表,而是(大多数)变化的方法比不变化的方法需要更多的类型信息。下面的代码则工作得很好:&List&Integer& li = new ArrayList&Integer&();&li.add(new Integer(42));&List&?& lu =&System.out.println(lu.get(0));&为什么该代码能工作呢?对于lu,编译器一点都不知道List的类型参数的值。但是编译器比较聪明,它可以做一些类型推理。在本例中,它推断未知的类型参数必须扩展Object。(这个特定的推理没有太大的跳跃,但是编译器可以作出一些非常令人佩服的类型推理,后面就会看到(在底层细节 一节中)。所以它让您调用List.get()并推断返回类型为Object。&另一方面,下面的代码不能工作:&List&Integer& li = new ArrayList&Integer&();&li.add(new Integer(42));&List&?& lu =&lu.add(new Integer(43)); // error&在本例中,对于lu,编译器不能对List的类型参数作出足够严密的推理,以确定将Integer传递给List.add()是类型安全的。所以编译器将不允许您这么做。&以免您仍然认为编译器知道哪些方法更改列表的内容哪些不更改列表内容,请注意下面的代码将能工作,因为它不依赖于编译器必须知道关于lu的类型参数的任何信息:&List&Integer& li = new ArrayList&Integer&();&li.add(new Integer(42));&List&?& lu =&lu.clear();&泛型方法&(在类型参数 一节中)您已经看到,通过在类的定义中添加一个形式类型参数列表,可以将类泛型化。方法也可以被泛型化,不管它们定义在其中的类是不是泛型化的。&泛型类在多个方法签名间实施类型约束。在List&V&中,类型参数V出现在get()、add()、contains()等方法的签名中。当创建一个Map&K, V&类型的变量时,您就在方法之间宣称一个类型约束。您传递给add()的值将与get()返回的值的类型相同。&类似地,之所以声明泛型方法,一般是因为您想要在该方法的多个参数之间宣称一个类型约束。例如,下面代码中的ifThenElse()方法,根据它的第一个参数的布尔值,它将返回第二个或第三个参数:&public &T& T ifThenElse(boolean b, T first, T second) {&return b ? first :&}&注意,您可以调用ifThenElse(),而不用显式地告诉编译器,您想要T的什么值。编译器不必显式地被告知 T 将具有什么值;它只知道这些值都必须相同。编译器允许您调用下面的代码,因为编译器可以使用类型推理来推断出,替代T的String满足所有的类型约束:&String s = ifThenElse(b, "a", "b");&类似地,您可以调用:&Integer i = ifThenElse(b, new Integer(1), new Integer(2));&但是,编译器不允许下面的代码,因为没有类型会满足所需的类型约束:&String s = ifThenElse(b, "pi", new Float(3.14));&为什么您选择使用泛型方法,而不是将类型T添加到类定义呢?(至少)有两种情况应该这样做:&* 当泛型方法是静态的时,这种情况下不能使用类类型参数。&* 当 T 上的类型约束对于方法真正是局部的时,这意味着没有在相同类的另一个 方法签名中使用相同 类型 T 的约束。通过使得泛型方法的类型参数对于方法是局部的,可以简化封闭类型的签名。&有限制类型&在前一屏泛型方法 的例子中,类型参数V是无约束的或无限制的类型。有时在还没有完全指定类型参数时,需要对类型参数指定附加的约束。&考虑例子Matrix类,它使用类型参数V,该参数由Number类来限制:&public class Matrix&V extends Number& { ... }&编译器允许您创建Matrix&Integer&或Matrix&Float&类型的变量,但是如果您试图定义Matrix&String&类型的变量,则会出现错误。类型参数V被判断为由Number限制。在没有类型限制时,假设类型参数由Object限制。这就是为什么前一屏泛型方法 中的例子,允许List.get()在List&?&上调用时返回Object,即使编译器不知道类型参数V的类型。一个很典型的泛型(generic)代码。T是类型变量,可以是任何引用类型:
public class Pair&T&{
private T first=null;
private T second=null;
public Pair(T fir,T sec){
this.first=
this.second=
public T getFirst(){
return this.
public T getSecond(){
return this.
public void setFirst(T fir){
this.first=
1、Generic class 创建对象
Pair&String& pair1=new Pair("string",1);
Pair&String& pair2=new Pair&String&("string",1)
有个很有趣的现象:
①代码在编译期不会出错,②代码在编译期会检查出错误。
这个问题其实很简单
(1) JVM本身并没有泛型对象这样的一个特殊概念。所有的泛型类对象在编译器会全部变成普通类对象(这一点会在下面详细阐述)。
比如①,②两个代码编译器全部调用的是 Pair(Object fir, Object sec)这样的构造器。
因此代码①中的new Pair("string",1)在编译器是没有问题的,毕竟编译器并不知道你创建的Pair类型中具体是哪一个类型变量T,而且编译器肯定了String对象和Integer对象都属于Object类型的。
但是一段运行pair1.getSecond()就会抛出ClassCastException异常。这是因为JVM会根据第一个参数"string"推算出T类型变量是String类型,这样getSecond也应该是返回String类型,然后编译器已经默认了second的操作数是一个值为1的Integer类型。当然就不符合JVM的运行要求了,不终止程序才怪。
(2) 但代码②会在编译器报错,是因为new Pair&String&("string",1)已经指明了创建对象pair2的类型变量T应该是String的。所以在编译期编译器就知道错误出在第二个参数Integer了。
小结一下:
创建泛型对象的时候,一定要指出类型变量T的具体类型。争取让编译器检查出错误,而不是留给JVM运行的时候抛出异常。
2、JVM如何理解泛型概念 —— 类型擦除
事实上,JVM并不知道泛型,所有的泛型在编译阶段就已经被处理成了普通类和方法。
处理方法很简单,我们叫做类型变量T的擦除(erased) 。
无论我们如何定义一个泛型类型,相应的都会有一个原始类型被自动提供。原始类型的名字就是擦除类型参数的泛型类型的名字。
如果泛型类型的类型变量没有限定(&T&) ,那么我们就用Object作为原始类型;
如果有限定(&T extends XClass&),我们就XClass作为原始类型;
如果有多个限定(&T extends XClass1&XClass2&),我们就用第一个边界的类型变量XClass1类作为原始类型;
比如上面的Pair&T&例子,编译器会把它当成被Object原始类型替代的普通类来替代。
//编译阶段:类型变量的擦除
public class Pair{
private Object first=null;
private Object second=null;
public Pair(Object fir,Object sec){
this.first=
this.second=
public Object getFirst(){
return this.
public void setFirst(Object fir){
this.first=
3、泛型约束和局限性—— 类型擦除所带来的麻烦
继承泛型类型的多态麻烦。(—— 子类没有覆盖住父类的方法 )
看看下面这个类SonPair
class SonPair extends Pair&String&{
public void setFirst(String fir){....}
很明显,程序员的本意是想在SonPair类中覆盖父类Pair&String&的setFirst(T fir)这个方法。但事实上,SonPair中的setFirst(String fir)方法根本没有覆盖住Pair&String&中的这个方法。
原因很简单,Pair&String&在编译阶段已经被类型擦除为Pair了,它的setFirst方法变成了setFirst(Object fir)。 那么SonPair中setFirst(String)当然无法覆盖住父类的setFirst(Object)了。
这对于多态来说确实是个不小的麻烦,我们看看编译器是如何解决这个问题的。
编译器 会自动在 SonPair中生成一个桥方法(bridge method ) :
public void setFirst(Object fir){
setFirst((String) fir)
这样,SonPair的桥方法确实能够覆盖泛型父类的setFirst(Object) 了。而且桥方法内部其实调用的是子类字节setFirst(String)方法。对于多态来说就没问题了。
问题还没有完,多态中的方法覆盖是可以了,但是桥方法却带来了一个疑问:
现在,假设 我们还想在 SonPair 中覆盖getFirst()方法呢?
class SonPair extends Pair&String&{
public String getFirst(){....}
由于需要桥方法来覆盖父类中的getFirst,编译器会自动在SonPair中生成一个 public Object getFirst()桥方法。
但是,疑问来了,SonPair中出现了两个方法签名一样的方法(只是返回类型不同):
①String getFirst()
// 自己定义的方法
②Object getFirst()
编译器生成的桥方法
难道,编译器允许出现方法签名相同的多个方法存在于一个类中吗?
事实上有一个知识点可能大家都不知道:
① 方法签名 确实只有方法名+参数列表 。这毫无疑问!
② 我们绝对不能编写出方法签名一样的多个方法 。如果这样写程序,编译器是不会放过的。这也毫无疑问!
③ 最重要的一点是:JVM会用参数类型和返回类型来确定一个方法。 一旦编译器通过某种方式自己编译出方法签名一样的两个方法(只能编译器自己来创造这种奇迹,我们程序员却不能人为的编写这种代码)。JVM还是能够分清楚这些方法的,前提是需要返回类型不一样。
(2) 泛型类型中的方法冲突
//在上面代码中加入equals方法
public class Pair&T&{
public boolean equals(T value){
return (first.equals(value));
这样看似乎没有问题的代码连编译器都通过不了:
Name clash: The method equals(T) of type Pair&T& has the same erasure as equals(Object) of type Object but does not override it。
编译器说你的方法与Object中的方法冲突了。这是为什么?
开始我也不太明白这个问题,觉得好像编译器帮助我们使得equals(T)这样的方法覆盖上了Object中的equals(Object)。经过大家的讨论,我觉得应该这么解释这个问题?
首先、我们都知道子类方法要覆盖,必须与父类方法具有相同的方法签名(方法名+参数列表)。而且必须保证子类的访问权限&=父类的访问权限。这是大家都知道的事实。
然后、在上面的代码中,当编译器看到Pair&T&中的equals(T)方法时,第一反应当然是equals(T)没有覆盖住父类Object中的equals(Object)了。
接着、编译器将泛型代码中的T用Object替代(擦除)。突然发现擦除以后equals(T)变成了equals(Object),糟糕了,这个方法与Object类中的equals一样了。基于开始确定没有覆盖这样一个想法,编译器彻底的疯了(精神分裂)。然后得出两个结论:①坚持原来的思想:没有覆盖。但现在一样造成了方法冲突了。
②写这程序的程序员疯了(哈哈)。
再说了,拿Pair&T&对象和T对象比较equals,就像牛头对比马嘴,哈哈,逻辑上也不通呀。
(3) 没有泛型数组一说
Pair&String&[] stringPairs=new Pair&String&[10];
Pair&Integer&[] intPairs=new Pair&Integer&[10];
这种写法编译器会指定一个Cannot create a generic array of Pair&String&的错误
我们说过泛型擦除之后,Pair&String&[]会变成Pair[],进而又可以转换为Object[];
假设泛型数组存在,那么
Object[0]=stringPairs[0]; Ok
Object[1]=intPairs[0]; Ok
这就麻烦了,理论上将Object[]可以存储所有Pair对象,但这些Pair对象是泛型对象,他们的类型变量都不一样,那么调用每一个Object[]数组元素的对象方法可能都会得到不同的记过,也许是个字符串,也许是整形,这对于JVM可是无法预料的。
记住: 数组必须牢记它的元素类型,也就是所有的元素对象都必须一个样,泛型类型恰恰做不到这一点。即使Pair&String&,Pair&Integer&... 都是Pair类型的,但他们还是不一样。
总结:泛型代码与JVM
① 虚拟机中没有泛型,只有普通类和方法。
② 在编译阶段,所有泛型类的类型参数都会被Object或者它们的限定边界来替换。(类型擦除)
③ 在继承泛型类型的时候,桥方法的合成是为了避免类型变量擦除所带来的多态灾难。
JVM如何理解Java泛型类
JVM如何理解Java泛型类
JVM如何理解Java泛型类
//泛型代码
public class Pair{
private T first=
private T sec...
Java JVM如何理解Java泛型类
/泛型代码 public class Pair{ private T first= private T second= public Pair(T fir,T sec){ this...
JVM理解其实并不难!
我的简书同步发布:JVM理解其实并不难!
在阅读本文之前,先向大家强烈推荐一下周志明的《深入理解Java虚拟机》这本书。前些天面试了阿里的实习生,问到关于Dalvik虚拟机能不能执行class文件,我...
关于 JVM 简单理解
JVM 笔记最近在看《深入理解java虚拟机》 jvm高级特性与最佳实践,下面是一些简单的个人笔记和理解,如果有错欢迎指出。1.java运行时数据区域:没错,图片是从网上找的。
其中:方法区和堆是所...
【解惑】JVM如何理解Java泛型类
//泛型代码
public class Pair{
private T first=
private T second=null...
谈谈你对JVM的理解
这里和大家简单分享一下JAVA和JVM运行的原理,Java语言写的源程序通过Java编译器,编译成与平台无关的‘字节码程序’(.class文件,也就是0,1二进制程序),然后在OS之上的Java解释器...
深入理解Java虚拟机总结
花了几天学习完了周志明老师写的《深入理解Java虚拟机–JVM高级特性与最佳实践》一书,为更加深入的理解以及日后复习之用,写一篇总结...
【泛型——这才真正的理解你】
曾记得那是机房重构,曾记得那是刚刚听说有泛型这个东西,曾记得自己实现了datatable转泛型的实例,而面对泛型,只知道它像一个集合一样,存储着信息。然而,今天对于泛型的认识,让我认识到了什...
没有更多推荐了,

我要回帖

更多关于 javajvm优化 的文章

 

随机推荐