泛型newjava(泛型的作用是支持类型)

华为云服务器特价优惠火热进行中!

2核2G2兆仅需 38 元;4核4G3兆仅需 79 元。购买时间越长越优惠!更多配置及优惠价格请咨询客服。

合作流程:
1、点击链接注册/关联华为云账号:点击跳转
2、添加客服微信号:cloud7591,确定产品方案、价格方案、服务支持方案等;
3、客服协助购买,并拉微信技术服务群,享受一对一免费技术支持服务;
技术专家在金蝶、华为、腾讯原厂有多年工作经验,并已从事云计算服务8年,可对域名、备案、网站搭建、系统部署、AI人工智能、云资源规划等上云常见问题提供更专业靠谱的服务,对相应产品提供更优惠的报价和方案,欢迎咨询。

本篇文章给大家谈谈泛型newjava,以及泛型的作用是支持类型对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

微信号:cloud7591
如需了解更多,欢迎添加客服微信咨询。
复制微信号

本文目录一览:

麻烦给我详细介绍下JAVA中用了泛型的好处,是不是用了泛型就可以不用NEW去创建对象了?

1. 泛型的却很有用, 如果跟反射可以配合用好, 普通企业应用得代码量可以减少非常多.

2. python之类type inference语言比java更适合做这种template抽象

举个例子: 企业程序大部分程序是实体信息管理得, 真正涉及交易清算得只有极小一部分

对于所有得实体管理, 基本上都是增,删, 改, 查看, 查找等等几个功能

我现在用了几个框架, 经典结合方式:webwork+spring+hibernate, 分析如下:

hibernate O/R Mapping没什么花头, 为每个实体管理都要写一个映射类, 一般跟实体得数目差不多, 有时候为了避免关联, 建几个视图映射会多点. But, 这个能用hibernate自己写得工具生成, 维护一个java类文件, 以及里面得meta description.

或者自己写个程序生成( 给定数据源,, 输出java类文件, 以及hbm .xml文件 ), 这个只需要维护sql语句就兴了, 我通常这么做.

1. 不用泛型, 不用反射

spring层要写5个service(假设一个实体对应一个service), 分别实现读实体, 加实体, 删实体, 根据条件查找实体List这些功能.

要写5个不同得实体类得Action, 然后Action里面实现校验, 增加, 修改, 删除, 列表得功能, 每一个类要实现得功能同样也类似.

这些都没多少重构实质性得体现, 好处不明显, 可以提取得公共代码非常少.

2. 不用泛型, 用反射

在 1 得基础之上, 可以重构提取出一个公共service, 将分散在5个service得公共代码kill掉. 多出一个根据实体类参数操作得公共类, 但是类得数量增加一个.

同样Action也可以提出一个baseaction来

重构消去了一部分代码, 每个service得代码还是存在重复代码, 但是这个还可以通过反射合成一个service, 不过掉用者要用反射调用

对于action因为需要配置, 除非webwork支持类型得注入, 否则, 不好消去.

如果webwork spring 支持实体类型得注入, 那么到此可以结束, 只写一套逻辑, 代码也没有重复, 由于精力有限, 没有去深入研究spring AOP跟webwork 得inteceptor机制, 不知道支持不支持.

3.用泛型, 用反射

在1得基础上引入泛型, 写一个泛型service, 写一个泛型webwork action , 也没有研究过xwork中泛型对象是怎么配置产生得, 如果支持配置, 只需要写一个action即可, 如果不支持, 需要为每个实体类写一个webwork action

同样页面也是这个样子

但是, java得泛型用了一把, 不说对很多东西支持得很差, 光写法上来看, 跟C++ template一致, 仍然是一大堆得, 让初学者吐血, 变成高手炫耀得奇技淫巧. 比起python之类动态类型安全语言type inference机制相差太远, java泛型还有很长得路要走, 不过静态语言走到type inference上来得话, 编译类型检查得好处就没了, 所以java这方面永远不可能~~~

通过上面考虑, 我觉得python更适合web管理程序, 对于很多entity management得程序完全可以写出一个服务所有, 仅仅是O?Rmapping就没办法省. 不知道python有没有类似java得反射, 如果有得话会更好, 可以写出更通用, 量更少得代码. 相信ruby on rails成功也有这方面得原因(我没用过ruby, 错了也别骂我), 毕竟代码越少越好, 尤其是重复代码

我得主张是kill掉all重复代码, 只要能抽象统一得代码重复就是罪过, 哈哈, 相信用python可以把这个做得更好, 越来越喜欢python语言得特性了, 可惜还没拿他来做过web程序

java中什么叫泛型?

泛型。规定了此集合中元素的类型。例如:\x0d\x0a\x0d\x0aArrayList arr = new ArrayList ();\x0d\x0a\x0d\x0a这样就创建了一个包含整数的 ArrayList 对象。\x0d\x0a如果要自己定义泛型类,就用如下形式:\x0d\x0a\x0d\x0aclass MyCollection {...}\x0d\x0a\x0d\x0a尖括号中的类型可以有限制,例如你需要让 MyCollection 中的类型都具有可比性,可以用如下格式:\x0d\x0a\x0d\x0aclass MyCollection {...}\x0d\x0a\x0d\x0a此外,要注意泛型的一些特性:\x0d\x0a\x0d\x0a1. 不能直接创建泛型数组。如 new ArrayList[5] 之类的是错的。只能用如下方法:new ArrayList[5] 或者 (ArrayList[])new ArrayList[5];\x0d\x0a\x0d\x0a2. 静态方法中需要小心,因为 E 一般是非静态类型,如果你这样写:\x0d\x0a class MyCollection {\x0d\x0a public static MyCollection abc() {\x0d\x0a ......\x0d\x0a }\x0d\x0a }\x0d\x0a 是错的。你只能把 去掉。

java 泛型对象能实例化吗T t=new T()

java中没法得到泛型参数化类型,因为在编译期没法确定泛型参数化类型,也就找不到对应的类字节码文件,自然就不行了

泛型反射的关键是获取ParameterizedType,再调用它的getActualTypeArguments()方法获得实际绑定的类型。但注意public class BookManagerBook是不能被反射的,因为擦拭法的缘故。只有在Superclass 或者成员变量(Field.getGenericType())等有函数返回ParameterizedType的时候才能成功反射,

你要么搞个构造函数把参数类型传进去才行

请教关于java的泛型方法

Java泛型详解

概述

在引入范型之前,Java类型分为原始类型、复杂类型,其中复杂类型分为数组和类。引入范型后,一个复杂类型

就可以在细分成更多的类型。

例如原先的类型List,现在在细分成ListObject, ListString等更多的类型。

注意,现在ListObject, ListString是两种不同的类型,

他们之间没有继承关系,即使String继承了Object。下面的代码是非法的

    ListString ls = new ArrayListString();

    ListObject lo = ls;

这样设计的原因在于,根据lo的声明,编译器允许你向lo中添加任意对象(例如Integer),但是此对象是

ListString,破坏了数据类型的完整性。

在引入范型之前,要在类中的方法支持多个数据类型,就需要对方法进行重载,在引入范型后,可以解决此问题

(多态),更进一步可以定义多个参数以及返回值之间的关系。

例如

public void write(Integer i, Integer[] ia);

public void write(Double  d, Double[] da);

的范型版本为

public T void write(T t, T[] ta);

2. 定义使用

 类型参数的命名风格为:

 推荐你用简练的名字作为形式类型参数的名字(如果可能,单个字符)。最好避免小写字母,这使它和其他的普通

 的形式参数很容易被区分开来。

 使用T代表类型,无论何时都没有比这更具体的类型来区分它。这经常见于泛型方法。如果有多个类型参数,我们

 可能使用字母表中T的临近的字母,比如S。

 如果一个泛型函数在一个泛型类里面出现,最好避免在方法的类型参数和类的类型参数中使用同样的名字来避免混

 淆。对内部类也是同样。

 

 2.1 定义带类型参数的类

 在定义带类型参数的类时,在紧跟类命之后的内,指定一个或多个类型参数的名字,同时也可以对类型参数的取

 值范围进行限定,多个类型参数之间用,号分隔。

 定义完类型参数后,可以在定义位置之后的类的几乎任意地方(静态块,静态属性,静态方法除外)使用类型参数,

 就像使用普通的类型一样。

 注意,父类定义的类型参数不能被子类继承。

 public class TestClassDefineT, S extends T {

     ....  

 }

 

 2.2 定义待类型参数方法

 在定义带类型参数的方法时,在紧跟可见范围修饰(例如public)之后的内,指定一个或多个类型参数的名字, 同时也可以对类型参数的取值范围进行限定,多个类型参数之间用,号分隔。

 定义完类型参数后,可以在定义位置之后的方法的任意地方使用类型参数,就像使用普通的类型一样。

 例如:

 public T, S extends T T testGenericMethodDefine(T t, S s){

     ...

 }

 注意:定义带类型参数的方法,骑主要目的是为了表达多个参数以及返回值之间的关系。例如本例子中T和S的继 承关系, 返回值的类型和第一个类型参数的值相同。

 如果仅仅是想实现多态,请优先使用通配符解决。通配符的内容见下面章节。

 public T void testGenericMethodDefine2(ListT s){

     ...

 }

 应改为

 public void testGenericMethodDefine2(List? s){

     ...

 }

 

3. 类型参数赋值

 当对类或方法的类型参数进行赋值时,要求对所有的类型参数进行赋值。否则,将得到一个编译错误。

 

 3.1 对带类型参数的类进行类型参数赋值

 对带类型参数的类进行类型参数赋值有两种方式

 第一声明类变量或者实例化时。例如

 ListString list;

 list = new ArrayListString;

 第二继承类或者实现接口时。例如

 public class MyListE extends ArrayListE implements ListE {...} 

 

 3.2 对带类型参数方法进行赋值

 当调用范型方法时,编译器自动对类型参数进行赋值,当不能成功赋值时报编译错误。例如

 public T T testGenericMethodDefine3(T t, ListT list){

     ...

 }

 public T T testGenericMethodDefine4(ListT list1, ListT list2){

     ...

 }

 

 Number n = null;

 Integer i = null;

 Object o = null;

 testGenericMethodDefine(n, i);//此时T为Number, S为Integer

 testGenericMethodDefine(o, i);//T为Object, S为Integer

 

 ListNumber list1 = null;

 testGenericMethodDefine3(i, list1)//此时T为Number

 

 ListInteger list2 = null;

 testGenericMethodDefine4(list1, list2)//编译报错

 

 3.3 通配符

 在上面两小节中,对是类型参数赋予具体的值,除此,还可以对类型参数赋予不确定值。例如

 List? unknownList;

 List? extends Number unknownNumberList;

 List? super Integer unknownBaseLineIntgerList; 

 注意: 在Java集合框架中,对于参数值是未知类型的容器类,只能读取其中元素,不能像其中添加元素, 因为,其类型是未知,所以编译器无法识别添加元素的类型和容器的类型是否兼容,唯一的例外是NULL

 ListString listString;

 List? unknownList2 = listString;

 unknownList = unknownList2;

 listString = unknownList;//编译错误

 

4. 数组范型

 可以使用带范型参数值的类声明数组,却不可有创建数组

 ListInteger[] iListArray;

 new ArrayListInteger[10];//编译时错误

 

5. 实现原理

5.1. Java范型时编译时技术,在运行时不包含范型信息,仅仅Class的实例中包含了类型参数的定义信息。

泛型是通过java编译器的称为擦除(erasure)的前端处理来实现的。你可以(基本上就是)把它认为是一个从源码到源码的转换,它把泛型版本转换成非泛型版本。

基本上,擦除去掉了所有的泛型类型信息。所有在尖括号之间的类型信息都被扔掉了,因此,比如说一个ListString类型被转换为List。所有对类型变量的引用被替换成类型变量的上限(通常是Object)。而且,无论何时结果代码类型不正确,会插入一个到合适类型的转换。

       T T badCast(T t, Object o) {

         return (T) o; // unchecked warning

       }

类型参数在运行时并不存在。这意味着它们不会添加任何的时间或者空间上的负担,这很好。不幸的是,这也意味着你不能依靠他们进行类型转换。

5.2.一个泛型类被其所有调用共享

下面的代码打印的结果是什么?

       ListString l1 = new ArrayListString();

       ListInteger l2 = new ArrayListInteger();

       System.out.println(l1.getClass() == l2.getClass());

或许你会说false,但是你想错了。它打印出true。因为一个泛型类的所有实例在运行时具有相同的运行时类(class),

而不管他们的实际类型参数。

事实上,泛型之所以叫泛型,就是因为它对所有其可能的类型参数,有同样的行为;同样的类可以被当作许多不同的类型。作为一个结果,类的静态变量和方法也在所有的实例间共享。这就是为什么在静态方法或静态初始化代码中或者在静态变量的声明和初始化时使用类型参数(类型参数是属于具体实例的)是不合法的原因。

5.3. 转型和instanceof

泛型类被所有其实例(instances)共享的另一个暗示是检查一个实例是不是一个特定类型的泛型类是没有意义的。

       Collection cs = new ArrayListString();

       if (cs instanceof CollectionString) { ...} // 非法

类似的,如下的类型转换

CollectionString cstr = (CollectionString) cs;

得到一个unchecked warning,因为运行时环境不会为你作这样的检查。

6. Class的范型处理

Java 5之后,Class变成范型化了。

JDK1.5中一个变化是类 java.lang.Class是泛型化的。这是把泛型扩展到容器类之外的一个很有意思的例子。

现在,Class有一个类型参数T, 你很可能会问,T 代表什么?它代表Class对象代表的类型。比如说,

String.class类型代表 ClassString,Serializable.class代表 ClassSerializable。

这可以被用来提高你的反射代码的类型安全。

特别的,因为 Class的 newInstance() 方法现在返回一个T, 你可以在使用反射创建对象时得到更精确的类型。

比如说,假定你要写一个工具方法来进行一个数据库查询,给定一个SQL语句,并返回一个数据库中符合查询条件

的对象集合(collection)。

一个方法是显式的传递一个工厂对象,像下面的代码:

interface FactoryT {

      public T[] make();

}

public T CollectionT select(FactoryT factory, String statement) { 

       CollectionT result = new ArrayListT();

       /* run sql query using jdbc */

       for ( int i=0; i10; i++ ) { /* iterate over jdbc results */

            T item = factory.make();

            /* use reflection and set all of item’s fields from sql results */

            result.add( item );

       }

       return result;

}

你可以这样调用:

select(new FactoryEmpInfo(){ 

    public EmpInfo make() { 

        return new EmpInfo();

        }

       } , ”selection string”);

也可以声明一个类 EmpInfoFactory 来支持接口 Factory:

class EmpInfoFactory implements FactoryEmpInfo { ...

    public EmpInfo make() { return new EmpInfo();}

}

然后调用:

select(getMyEmpInfoFactory(), "selection string");

这个解决方案的缺点是它需要下面的二者之一:

调用处那冗长的匿名工厂类,或为每个要使用的类型声明一个工厂类并传递其对象给调用的地方,这很不自然。

使用class类型参数值是非常自然的,它可以被反射使用。没有泛型的代码可能是:

Collection emps = sqlUtility.select(EmpInfo.class, ”select * from emps”); ...

public static Collection select(Class c, String sqlStatement) { 

    Collection result = new ArrayList();

    /* run sql query using jdbc */

    for ( /* iterate over jdbc results */ ) { 

        Object item = c.newInstance();

        /* use reflection and set all of item’s fields from sql results */

        result.add(item);

    }

        return result;

}

但是这不能给我们返回一个我们要的精确类型的集合。现在Class是泛型的,我们可以写:

CollectionEmpInfo emps=sqlUtility.select(EmpInfo.class, ”select * from emps”); ...

public static T CollectionT select(ClassTc, String sqlStatement) { 

    CollectionT result = new ArrayListT();

    /* run sql query using jdbc */

    for ( /* iterate over jdbc results */ ) { 

        T item = c.newInstance();

        /* use reflection and set all of item’s fields from sql results */

        result.add(item);

    } 

    return result;

}

来通过一种类型安全的方式得到我们要的集合。

这项技术是一个非常有用的技巧,它已成为一个在处理注释(annotations)的新API中被广泛使用的习惯用法。

7. 新老代码兼容

7.1. 为了保证代码的兼容性,下面的代码编译器(javac)允许,类型安全有你自己保证

List l = new ArrayListString();

ListString l = new ArrayList();

7.2. 在将你的类库升级为范型版本时,慎用协变式返回值。

例如,将代码

public class Foo { 

    public Foo create(){

        return new Foo();

    }

}

public class Bar extends Foo { 

    public Foo create(){

        return new Bar();

    } 

}

采用协变式返回值风格,将Bar修改为

public class Bar extends Foo { 

    public Bar create(){

        return new Bar();

    } 

}

要小心你类库的客户端。

关于泛型newjava和泛型的作用是支持类型的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

发布于 2023-03-31 23:03:22
收藏
分享
海报
36
目录

    忘记密码?

    图形验证码

    复制成功
    微信号: cloud7591
    如需了解更多,欢迎添加客服微信咨询。
    我知道了