首页 > 编程知识 正文

java代码看不懂怎么办,java越学越迷茫

时间:2023-05-05 02:23:26 阅读:137257 作者:3013

首先在学习java转弯的日子里,很多青年都走穴了,同时也有很多青年进洞了,进洞的时候可能没有什么好的指导或者没有学习的方法。 头发脱落可能会一发不可收拾……

有一个cdsh有着同样的遭遇,后辈泛着晕,不知道泛是什么。 不知道每天使用的通用的东西是什么。 作为证据制图! 当然,笔者的深度还不够,如有错误请指正!

本篇根据笔者的理解是简单的介绍通用的(加深需要自身),如果深度不够或有错误,请谅解。

总称是什么:

通用性是编程语言的特性。 使程序员能够定义用强大的编程语言编写代码时,在使用之前必须指定的可变部分。 各种编程语言及其编译器、运行环境对通用性的支持不同。 一种数据类型,通过参数化类型实现代码复用,提高软件开发的工作效率。 泛型类是引用类型,是堆对象,主要引入了类型参数的概念。

没有通用性时是通用的,从字面意义上来说,从广义上讲是能够广泛代表或处理某一类事务的类型(java集合类)。 没有通用性的时候,怎么处理? 比如写链表的时候。 可能会变成这样:

公共类节点{公共int value; //节点结果node next; //下一个要连接的节点public node () public node intvalue ) { this.value=value; }该节点包含int类型,但对于包含字符串的链表或双精度型数据链表怎么办? 这样反复写吗:

公共类节点{公共字符串值; //节点结果node next; //下一个要连接的节点public node () public node ) stringvalue ) { this.value=value; }要改写吗? 请重写。

使用Object类表示通用地发现了设计中存在的这个大问题后,极大地考虑了这个问题的严重性和复杂性,随着面向对象的发展而流行起来,java有向上转型和http://www.Sina

向下转型:将子类的对象指定给父类类型的变量的技术称为app cast。 可以在父类中定义方法,并根据子类具体实现,这也是多态性机制的基本思想。

因为在很多情况下,我们的班级不一定越细越好。 例如,狗的共同点已经很相似了。 您可以使用向上转型操作一组狗,但它们已用不同的类型具体实例化,例如dog。 改写部分特殊函数,使用时直接使用dog的api即可满足要求。

java中这种多态性思想也非常多,例如:

listintegerlist1=newarraylistinteger (; listintegerlist2=newlinkedlistinteger (; 前面的上传是从更具体的类到更抽象的类的转换。 关于上传,当然有实例化可能根据哈士奇、藏獒、金毛。 向下广播是指将更抽象的类转换为更具体的类。 当然向下变换需要强制进行类型变换。 (显示转换告诉编译器。 )

使用代码查看时:

public class test { publicstaticvoidmain (string [ ] args )//animal是指想要dog的堆地址,从dog—— ) animal向上一级分配animal animal animal.sayhello (; dog.sayhello (; }}class animal{ public String name; 公共输入页面; publicanimal(stringname,int age ) { this.name=name; this.age=age; } public void say hello ((system.out.println ),我是aninal' this.name '今年' this.age '岁); } classdogextendsanimal { public dog (string name,int age ) super ) name,age; } @Override public void sayhello () system.out.println ),我

是狗狗"+this.name+"今年"+age+"岁"); }}

我们知道在java中Object类为所有类的父类(超类)。它是站在最顶端的类型,所有类(class)都是它的子子孙孙,它自己写好了toString(),equalls()等方法。

而同理我们借鉴这种思想可以将一个类先向上转型成Object类,然后再将操作完的数向下转型成我们所需要的数。达到这种使用上的效果,但是基本类型无法满足这个要求啊,所以就出现了包装类这个东西。在储存对象时候一定程度上能够满足使用需求。

public class test { public static void main(String[] args) { Integer a=10; node node1=new node(a); Integer va1=(Integer) node1.getValue(); System.out.println(va1); node node2=new node("hello"); String va2=(String) node2.getValue(); System.out.println(va2); }}class node{ private Object value; public node(Object value) { this.value=value; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; }}

执行的结果为:

10hello

这种虽然一定程度能够达到泛型效果,但是除了功能受限、使用麻烦之外,还有个更大的毛病。就是在第二次显示的向下转向的时候,如果人为转换错误编译器无法识别,而必须等到代码执行时候才报错,这样的机制让java代码变得不太安全。

Java泛型

在Object显示转换存在不安全行为的情况下,Java在jdk1.5以后提出了泛型机制,通过泛型就能有效避免转型时候出现的问题,泛型简单的理解就是在类、接口、方法中定义未知类型变量,只有初始化的时候才知道真正的类型。在定义的类或接口函数中可以直接使用这个未知类型进行操作。

泛型类

泛型类的语法如下:

类名<T> 其中T代表一个类型名称类名<T1,T2> 可能有多个类型

其中T,T1,T2都叫做通配符。常用的通配符有T,E,K,V分别表示类型、元素、键、值,当然这并不是硬性规定,而是大家形成的一种通识。

你在创建node类就可以使用如下的写法了:

public class node <T>{ private T value; public node(T value) { this.value = value; } public T getValue() { return value; } public void setValue(T value) { this.value = value; }}

其中T就可以在类中自由使用,这个类我们暂时不知道是什么,但是初始化的时候编译器就知道它是什么类型:

泛型接口

既然类可以使用泛型,接口当然也可以,不过接口使用泛型和普通类的略有区别,子类在继承泛型接口的时候需要接口处声明泛型类型,否则编译器报错。例如下面的pig类。

而如果你依然想在子类中使用泛型,那就需要在子类中声明一个泛型,而接口中的泛型使用子类的泛型类型。例如下面的dog类。

interface aninal <T>{ T getValue(T t);}class cat implements aninal {//用默认Object类型 @Override public Object getValue(Object o) { return o; }}class pig implements aninal<String>{//子类不设置泛型,父类接口的泛型需要明确类型 @Override public String getValue(String s) { return s+"哼哼"; }}class dog <T>implements aninal<T> {//子类和接口均使用泛型。 @Override public T getValue(T t) { return t; }}

也就是说使用泛型接口如果进行继承依然想使用泛型就需要在继承的类中事先定义好接口部分的泛型类供接口使用。

class 类 <A,B,C>implements aninal<C> 泛型方法

泛型函数的基本使用也很容易,和泛型类和泛型接口使用很相似,不过就是菱形需要放到函数类型前面:

public <T1,T2> void fuc(T1 t1,T2 t2){ System.out.println(t1); System.out.println(t2); } 边界限定

泛型既然这么好用,可以在使用时候直接传入具体类型,但是我们在开发很多时候某个类或者某个方法的能够传入类型是有限制的。那么在java中有上边界限定和下边界限定用来限制泛型的可用类型。
限定通配符包括两种:

类型的上界,格式为:<? extends T>,即类型必须为T类型或者T子类

类型的下界,格式为:<? super T>,即类型必须为T类型或者T的父类

举个例子在Java中编写这些类和方法:

class animal { //dosomething}class dog extends animal { //dosomething}class pig extends animal { //dosomething}public class test { static void printlist1(List<? extends animal>list)//只能aninal和animal的子类 { for(animal animal:list) { System.out.println(animal); } } static void dolist2(List<? super pig>list) { //dosomething }}

这样printlist1函数就使用了上边界限定。而dolist2函数就用了泛型的下边界限定,ykddb错误运用时候编译器就可以提示出来。

尾声

当然本篇并不是一个完整的泛型解答和总结,泛型还有很多细致的需要对比其差别这里就先不介绍啦。

从整体来讲,泛型的主要作用还是为了解决类型转换的安全性问题,避免了Object来回转换的问题,使得编译器就能识别类型转换的错误,同时通过限定类型使得函数方法等使用的更加灵活方便。不过泛型更多的应用于框架的编写方面,在java中其实也是随处可见。尤其是集合类:


看了这篇泛型,下次设计链表二叉树别傻傻的用int 表示node节点的值了!我想你该知道正确的写法了!

给cdsh发了之后:

累哉!

如果感觉不错,还请关注、点赞、收藏一键三联,另外笔者微信公众号:bigsai 更多学习资料、精彩内容与你分享!

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。