我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语:
public void GreetPeople(string name) {
// 做某些额外的事情,比如初始化之类,此处略
EnglishGreeting(name);
}
public void EnglishGreeting(string name) {
ConsoleWriteLine("Morning, " + name);
}
暂且不管这两个方法有没有什么实际意义。GreetPeople用于向某人问好,当我们传递代表某人姓名的name参数,比如说“Jimmy”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再次传递name参数,EnglishGreeting则用于向屏幕输出 “Morning, Jimmy”。
现在假设这个程序需要进行全球化,哎呀,不好了,我是中国人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法:
public void ChineseGreeting(string name){
ConsoleWriteLine("早上好, " + name);
}
这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据:
public enum Language{
English, Chinese
}
public void GreetPeople(string name, Language lang){
//做某些额外的事情,比如初始化之类,此处略
swith(lang){
case LanguageEnglish:
EnglishGreeting(name);
break;
case LanguageChinese:
ChineseGreeting(name);
break;
}
}
OK,尽管这样解决了问题,但我不说大家也很容易想到,这个解决方案的可扩展性很差,如果日后我们需要再添加韩文版、日文版,就不得不反复修改枚举和GreetPeople()方法,以适应新的需求。
在考虑新的解决方案之前,我们先看看 GreetPeople的方法签名:
public void GreetPeople(string name, Language lang)
仅看 string name,在这里,string 是参数类型,name 是参数变量,当我们赋给name字符串“jimmy”时,它就代表“jimmy”这个值;当我们赋给它“刘XX”时,它又代表着“刘XX”这个值。然后,我们可以在方法体内对这个name进行其他 *** 作。哎,这简直是废话么,刚学程序就知道了。
如果你再仔细想想,假如GreetPeople()方法可以接受一个参数变量,这个变量可以代表另一个方法,当我们给这个变量赋值 EnglishGreeting的时候,它代表着 EnglsihGreeting() 这个方法;当我们给它赋值ChineseGreeting 的时候,它又代表着ChineseGreeting()方法。我们将这个参数变量命名为 MakeGreeting,那么不是可以如同给name赋值时一样,在调用 GreetPeople()方法的时候,给这个MakeGreeting 参数也赋上值么(ChineseGreeting或者EnglsihGreeting等)?然后,我们在方法体内,也可以像使用别的参数一样使用MakeGreeting。但是,由于MakeGreeting代表着一个方法,它的使用方式应该和它被赋的方法(比如ChineseGreeting)是一样的,比如:
MakeGreeting(name);
好了,有了思路了,我们现在就来改改GreetPeople()方法,那么它应该是这个样子了:
public void GreetPeople(string name, MakeGreeting){
MakeGreeting(name);
}
注意到 ,这个位置通常放置的应该是参数的类型,但到目前为止,我们仅仅是想到应该有个可以代表方法的参数,并按这个思路去改写GreetPeople方法,现在就出现了一个大问题:这个代表着方法的MakeGreeting参数应该是什么类型的?
NOTE:这里已不再需要枚举了,因为在给MakeGreeting赋值的时候动态地决定使用哪个方法,是ChineseGreeting还是 EnglishGreeting,而在这个两个方法内部,已经对使用“morning”还是“早上好”作了区分。
聪明的你应该已经想到了,现在是委托该出场的时候了,但讲述委托之前,我们再看看MakeGreeting参数所能代表的 ChineseGreeting()和EnglishGreeting()方法的签名:
public void EnglishGreeting(string name)
public void ChineseGreeting(string name)
如同name可以接受String类型的“true”和“1”,但不能接受bool类型的true和int类型的1一样。MakeGreeting的 参数类型定义 应该能够确定 MakeGreeting可以代表的方法种类,再进一步讲,就是MakeGreeting可以代表的方法 的 参数类型和返回类型。
于是,委托出现了:它定义了MakeGreeting参数所能代表的方法的种类,也就是MakeGreeting参数的类型。
NOTE:如果上面这句话比较绕口,我把它翻译成这样:string 定义了name参数所能代表的值的种类,也就是name参数的类型。
本例中委托的定义:
public delegate void GreetingDelegate(string name);
可以与上面EnglishGreeting()方法的签名对比一下,除了加入了delegate关键字以外,其余的是不是完全一样?
现在,让我们再次改动GreetPeople()方法,如下所示:
public void GreetPeople(string name, GreetingDelegate MakeGreeting){
MakeGreeting(name);
}
如你所见,委托GreetingDelegate出现的位置与 string相同,string是一个类型,那么GreetingDelegate应该也是一个类型,或者叫类(Class)。但是委托的声明方式和类却完全不同,这是怎么一回事?实际上,委托在编译的时候确实会编译成类。因为Delegate是一个类,所以在任何可以声明类的地方都可以声明委托。更多的内容将在下面讲述,现在,请看看这个范例的完整代码:
using System;
using SystemCollectionsGeneric;
using SystemText;
namespace Delegate {
//定义委托,它定义了可以代表的方法的类型
public delegate void GreetingDelegate(string name);
class Program {
private static void EnglishGreeting(string name) {
ConsoleWriteLine("Morning, " + name);
}
private static void ChineseGreeting(string name) {
ConsoleWriteLine("早上好, " + name);
}
//注意此方法,它接受一个GreetingDelegate类型的方法作为参数
private static void GreetPeople(string name, GreetingDelegate MakeGreeting) {
MakeGreeting(name);
}
static void Main(string[] args) {
GreetPeople("Jimmy Zhang", EnglishGreeting);
GreetPeople("XXX", ChineseGreeting);
ConsoleReadKey();
}
}
}
输出如下:
Morning, Jimmy Zhang
早上好, XXX
现在对委托做一个总结:
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。
Java学习前的一些准备
JDK - (Java SE Development Kit)
JDK是Java开发所需要的环境,就跟我们想玩某个网游一样,玩之前一定是需要先安装相应的程序包的。 那这个JDK就是我们准备登陆Java大陆前需要安装的一个程序包。
下载地址 : Java SE - DownloadsIDE - (Integrated Development Environmen)
IDE是集成开发环境,一般集成开发环境都会带有JDK,可以使用自带的JDK也可以使用我们下载的JDK,不同的IDE配置不同。Java常用的IDE有Eclipse、MyEclipse、IntelliJ IDEA。IDE具备代码分析、补全、变异、调试等常用功能,可以大大的提高开发人员的编程效率。
eclipse下载地址 :书籍推荐
《Head First Java(中文版)(第2版)(涵盖Java50)》 塞若, 贝茨摘要 书评 试读图书>
阶段大致细节
1、入门基础
Java简介
了解什么是Java;代码语法基本格式;输出表达式。
了解Java大致的编译以及执行过程
Java语言基础、循环、数组 ; 了解类和对象
掌握Java的基本数据类型和引用数据类型有哪些;
掌握强制数据类型转换和自动类型提升规则;
常量如何声明及赋值;
循环的语法及作用;
数组的声明及定义;
掌握类的概念以及什么是对象。
OOP封装、继承、多态
面向对象的三大特征,本节内容非常重要也相对来说较为难以理解,一定要耐下心来好好理解。
javautil包下的常用类
util包下的Collection、Comparator、Iterator、List、Map、Set接口都很重要,着重看一下他们的实现类,如:ArrayList、LinkedList、HashSet、HashMap、Hashtable、TreeMap、TreeSet等。
javalang包下的常用类
lang包下的基本数据类型对应的包装类(Byte、Short、Integer、Long、Double、Float、Character、Boolean);
字符串相关的类String、StringBuffer、StringBuilder。
IO流 *** 作,多线程及Socket
掌握IO读写流相关的类,了解字节流,字符流和字符流缓冲区;
掌握线程的概念,多线程的创建、启动方式,锁和同步的概念及运用;
掌握Socket通信的概念,如何声明客户端服务端,如何完成双端数据通信。
泛型、数据库基础(Mysql)及JDBC
到了数据库前,我们可以看看泛型以及反射的一些基础案例
掌握数据库的基本概念,Mysql的安装、启动与停止
Mysql数据库客户端的安装与使用
JDBC的概念,在Java中使用Mysql驱动包连接Mysql
Mysql社区版下载 : Download MySQL Community Server 客户端连接工具 Navicat for Mysql下载 : MySQL Database Administration and Development Tool通过第一阶段的学习掌握Java语法和常用类,数据库入门技术相关知识。让自己对于存储,IO,这些有个大概的了解。这时候,暂时不需要花大量的精力以及篇幅去学习多线程和Socket,当然这里不是说他们不重要,而是对于现阶段的你,或许很难非常清晰的明白以及了解他们具体的作用。这里第一节忽略掉了Swing,Swing章节的内容可以不学,因为在实际的工作中基本上没有用武之地。
使用第一阶段的技术完成一个小型的系统,找一个自己做容易理解的系统练练手,比如超市管理系统、成绩管理系统等等这类需求简单却能讲整章内容结合起来使用的项目。当然这个时候可能会有人觉得没有图形界面没法完成系统 *** 作。实际上我们可以通过Console的输入输出来做系统界面。
新手在第一阶段的学习时,是最难熬的,因为这个时候需要背的东西特别多,且不再像看小说一样,什么东西都能看明白。路就变成了前面熟悉,左右陌生。这个时候人的求知欲作祟,往往会把自己带着偏移了方向,因为我们自己也不知道这样走对不对。渐而远之,也就慢慢放弃了。而这样的放弃,是最不值得的。所以,学习Java一定要按照某一个大纲,一直往下不要往其他地方偏,先走完一遍之后,再回头慢慢捡。
2、前端基础
HTML基本标签、表格、表单和框架;
掌握网页的基本构成;
掌握HTML的基本语法;
表格的作用以及合并行、合并列;
表单标签的使用,提交方式get/post的区别;
框架布局的使用
CSS样式表;
掌握CSS的语法及作用,在html中的声明方式;
掌握CSS布局的函数使用;
掌握CSS外部样式的引入。
JavaScript;
掌握JS的语法及作用,在HTML中的声明方式;
掌握JS的运行方式;
掌握JS中的变量声明、函数声明、参数传递等;
掌握HTML中的标签事件使用;
掌握JS中的DOM原型
上述三节都可以查看w3school : HTML 系列教程jQuery
了解如何使用jQuery,下载最新版或者老版本的jQueryjs
掌握选择器、文档处理、属性、事件等语法及使用;
能够灵活使用选择器查找到想要查找的元素并 *** 作他们的属性;
动态声明事件;
动态创建元素。
jQuery文档 : jQuery API 中文文档 | jQuery API 中文在线手册 | jquery api 下载 | jquery api chmBootStrap;
掌握BootStrap的设计理念,以及使用方式。这是我们需要接触的第一个前端框架,使用起来也很简单;
掌握BootStrap的栅格系统、表单、全局样式、分页工具栏、模态框等。
Servlet
掌握Java中的Web项目目录结构;
掌握Java Web项目的重要中间件Tomcat;
掌握Servlet中的Request和Response;
掌握Servlet的基本运行过程。
掌握Servlet的声明周期
动态网页技术
JSP在Java Web中的角色;
JSP的编码规范,以及JSPServlet;
JSP显示乱码的解决办法等。
JSP数据交互
JSP中如何编写Java代码,如何使用Java中的类;
JSP中的参数传递。
状态管理Session和Cookie
掌握Session的作用及作用域;
掌握Cookie的作用及作用域;
掌握Session及Cookie的区别,存储位置,声明周期等;
掌握Session及Cookie分别在JSP和Cookie中的使用
JSTL和EL表达式
使用EL表达式输出page、request、session、application作用域中的值
使用JSTL来做逻辑判断或循环控制
JNDI数据库连接池
JNDI的作用以及如何使用JNDI连接数据库
分页和文件上传
掌握在JSP中如何使数据达到分页的目的;
掌握在JSP表单中如何上传文件,Servlet如何处理上传请求(Commons-Fileupload、Commons-IO)。
Ajax
掌握Ajax的基本概念;
掌握jQuery中的Ajax请求;
掌握JSON
Filter、Listener;
掌握Filter和Listener
掌握Session过滤器和编码过滤器
通过第二阶段了解前端相关的技术,如果你喜欢前端各种酷炫的效果,那么就深入学习JS、CSS。不大感兴趣的话,就浅尝辄止,并重点学习Servlet、Filter、Listener。重点学习,重点学习,重点学习。 重要的话说三遍!
学习完第二阶段的内容之后,就可以进行B/S版本的系统开发了。这个时候我们可以挑选个稍微复杂点儿的项目来练练手,能找到商业项目练手的那是最好不过的,没有的话,就写写学生管理系统,档案管理系统,人事管理系统之类的练练手吧。
最后说一下本阶段的前端知识,如果将jQuery和Bootstrap学的差不多了的话,再看EasyUI这之类的前端框架也基本上都是照着API用就行了。别害怕看API,看API将是你以为的整个职场生涯必不可少的一个技能。
3、 主流技术应用
Mybatis的应用
Mybatis的Mapping与实体映射;
Mybatis中的SQL语句写法;
Mybatis的缓存。
Spring应用
Spring容器的作用;
Spring的AOP和IOC;
Spring托管Mybatis事务;
SpringMVC的应用
SpringMVC中的控制器注解、请求注解、参数注解、响应注解等;
SpringMVC中的静态资源处理;
SpringMVC的容器。
Spring+SpringMVC+Mybatis整合
SSM的整合使用;
Spring容器和SpringMVC容器
Redis+Mysql的查询优化设计
Redis的安装与连接;
Redis常用命令及各命令使用场景;
Redis存储机制;
Redis的持久化机制。
任务处理相关
>
Quartz定时任务
常用工具
Excel&World导入导出
短信&邮件发送
Maven
Maven的作用
Maven项目的创建
Maven的生命周期
Maven中央仓库及私服
Log4J2日志
FastDFS的使用
什么是分布式文件系统;
分布式文件系统解决的问题是什么;
FastDFS的使用
通过第三阶段了解目前Java领域比较经典的三大框架,了解他们的大概功能,并加以使用。通过使用SSM开发一个简易CRM之类的项目来加强了解,理清楚框架的大致原理。搞清楚这三个框架之间的作用域以及角色。理解Redis作为内存数据库与MySQL这类关系型数据库的区别,并能使用常用的Jar包完成模拟请求,定时任务等相关系统常用功能的开发。并能够通过Maven创建SSM项目,整合Log4j或其他的日志包。了解FastDFS的作用,并理解上传至文件服务器和上传到tomcat之间的区别
在第三阶段的内容学习完了之后,就应该对整个系统研发有个大概的印象,实际上这个时候,独立完成一个系统之后,再回过头来仔细思考下Servlet+JDBC+JSP与SSM实现项目的相同点及区别。这样会让你更加的有收获。并能够理解非关系型数据库Redis的性能优势以及使用场景。
4、模拟实际项目开发
SpringBoot 20的应用
了解SpringBoot的起源及优势
了解SpringBoot项目的格式以及创建方式
yaml语法特性
application配置文件及静态资源处理
Thymeleaf模板引擎
SpringBoot核心之WebMVCConfigurer
Spring自定义错误处理
SpringBoot日志引用及切换
SpringBoot数据源和Mybatis
SpringBoot-redis应用
Struts2应用(了解即可)
通过学习Struts,了解什么是MVC;
掌握Struts是如何完成界面控制的;
掌握Struts的参数接收及传递;
掌握Struts的拦截器;
掌握Struts的OGNL和标签使用。
Hibernate应用(了解即可)
Hibernate在项目中的作用及优势;
Hibernate中的hbm与实体类之间的关系;
什么是HQL,什么是关系映射(一对一,多对一,多对多);
了解Hibernate的事务、懒加载和缓存。
Redis哨兵模式的搭建
Linux *** 作系统
Linux中的常用命令;
Linux下的JDK、tomcat安装;
Linux下的项目部署方式。
Nginx的使用
Nginx的作用;
反向代理和正向代理分别是什么;
Nginx实现tomcat代理。
Mysql集群方案
Mysql集群的常用方案有哪些;
Mycat中间件的概念
Mycat的使用准则;
了解数据库的主从复制;
了解数据库的主备切换;
为什么需要主从和主备。
Solr入门
什么是全文检索;
Solr做搜索的优势是什么;
Lucene、ElasticSearch、Solr之间的关系;
Solr的安装与使用。
JVM
回顾所有所学习到的知识,联系所有框架中的自定义容器、上下文来理解变量及对象的存储
理解垃圾回收是怎么一回事
理解集中回收算法
完全理解整个堆栈模型
通过第四个阶段了解更简单易用的SpringBoot,微服务应用和存储集群相关的概念及实现方案。让自己具备一个设计高可用,可扩展的项目框架视野。这样对于后面继续专研SpringCloud / Dubbo、zookeeper这些RPC相关的框架有很大的好处。
第四阶段的内容更加偏向于互联网技术栈,通过这一节的内容能够脱离出基本的增删改查,了解出了增删查改之后,需要了解的集群、系统性能优化、外部缓存服务器使用、集群负载等概念。这些思维对于后面的提高以及学习会很有好处。
我提到的这些东西都能搜到对应的资料,无非多踩点坑罢了。但是,看文档or项目永远进步不了。一定要上手敲,想再多也不如动手。有机会联系一名优秀学长,有个走在前面的人给你指路肯定比你自己走要快得多。
最后,一定要动手,一定要动手,一定要动手。把代码敲烂,你才会有收获,不要被视频诱导,敲一遍之后误认为你自己会了,如果第二天你起来时已经忘了昨天学习了什么的话,那说明你还是没学会。好好加油吧。
在所有的学习过程中,每一个节点都应该有相应的练习或者项目来进行练手,看再多的博文和视频都是不行的, 不能让自己的双手停下来,只有不停的敲打键盘,写出自己的项目,然后在实际的开发中学会如何使用debug,总结所有遇到的bug及解决思路,这样才叫做学习技术。所以,希望有兴趣的同学,能够好好努力,不要因为一点点难度就懈怠、放弃。开发这条路途,无论你工作多久,都会遇到各种奇奇怪怪的问题,以及形形色色的bug等着你去解决。
在CLR10中,要创建一个灵活的类或方法,但该类或方法在编译期间不知道使用什么类,就必须以Object类为基础。而Object类在编译期间没有类型安全性。因此必须进行强制类型转换。另外,给值类型使用Object类会有性能损失。
CLR20(Net
35
基于CLR20)提供了泛型。有了泛型,就不需要Objcet类。
SystemCollectionsGeneric命名空间中的List
<T>类不使用对象,而是在使用定义类型。
泛型优点1:性能。
值类型存储在堆栈上,引用类型储存在堆上。
C#类是引用类型,结构是值类型。Net很容易把值类型转换为引用类型。所以可以在需要对象(对象是引用类型)的任意地方使用值类型。
例如:int可以赋予一个对象,从值类型转换为引用类型成为装箱,如果方法需要吧一个对象作为参数,而且传送了一个值类型。装箱 *** 作就会自动进行。另一方面,装箱的值类型可以使用拆箱 *** 作转换为值类型。在拆箱时,需要使用类型转换运算符。
装箱和拆箱 *** 作性能损失比较大。遍历许多项时尤其如此。
SystemCollectionsGenriec名称空间中的List<T>类不使用对象,而是在使用时定义类型。当List<T>的泛型类型定义为int,int类型在JIT编译器动态生成的类中使用,不再进行装箱和拆箱 *** 作
泛型优点2:类型安全
如果在ArrayList类中添加一个整数、一个字符串、一个MyClass类型的对象,如果这个集合使用Foreach语句迭代并转换为Int那么会出现异常。
在泛型类List<T>中,泛型类型T定义了允许使用的类型。有了List<int>的定义。就只能吧整数类型添加到集合中。
泛型优点3:二进制代码的重用。
泛型允许更好地重用二进制代码。泛型类定义一次,用许多不同的类型实例化。
泛型类型可以在一种语言中定义,在另一种Net
语言中使用。
泛型优点4:代码扩展。
泛型集合!!
指定List存放的类型;
程序分析:
这个程序是对数据库T_YW_KHXXB表进行查询的 *** 作;
1定义T_YW_KHXXB表所对应的实体Bank 其中每个属性与T_YW_KHXXB表中的字段一一对应
2声明sql查询语句 String sql = "SELECT DH,DZ,KHBH,ZJHM,XM FROM T_YW_KHXXB";
3List<Bank> list = new ArrayList<Bank>();定义一个集合存储Bank尸体对象对象
4PreparedStatement ps = conprepareStatement(sql);
ResultSet rs = psexecuteQuery();
执行SQL语句并返回ResultSet对象集(结果集)
5把结果集读取出来并存入List集合对象当中,让后返回这个List集合对象
既然你暗示就是ArrayList了,
首选就从Arraylist想了
可以试试:
import javautilArrayList;
public class Test{
public static void main(String[]args){
ArrayList<ArrayList<Integer>> als = new ArrayList<ArrayList<Integer>> ();
ArrayList<Integer> a1 = new ArrayList<Integer>();
ArrayList<Integer> a2 = new ArrayList<Integer>();
ArrayList<Integer> a3 = new ArrayList<Integer>();
ArrayList<Integer> a4 = new ArrayList<Integer>();
//下面是添加行,你可以用循环添加固定的行
//每一列就是一个ArrayList<Integer>,你可以任意添加,长度不固定吧
alsadd(a1);
alsadd(a2);
alsadd(a3);
alsadd(a4);
Systemoutprintln(alssize());
}
}
tao_3000的方法可行,只是Integer[]创建时要指定维数
可以自己写个算法自动增加维数
对于你说的数据量问题,个人理解是这样的:
达到了几十万几百万的数据量的时候,我想大概就是从数据库中吧数据读取出来,进行批量的处理或者更新之类的 *** 作。
你说得很对,如此庞大的数据量肯定会使效率降低,
但是我们完全可以一次从数据库中读取几百条记录,进行 *** 作
关于如何从数据库中一次读取很少的记录,jdbc和hibernate都有相应的实现
在者,数据量过大,呵呵,JVM可能崩溃哦 _
dr["列"];
你应该有一个实体类的
Entity et = new Entity();
etxx=dr["列"];
//将实体类的每个属性与你数据库的字段绑定就ok
listAdd(et) //最后将这个对象放到list就ok了
public string Name
{
get { return name; }
set { name = value; id = 1; }
}
protected void Page_Load(object sender, EventArgs e)
{
List<CatalogInfo> list = new List<CatalogInfo>
{
new CatalogInfo ()
{
Name = "Option 1"
},
new CatalogInfo()
{
Name = "Option 2"
}
};
thisDropDownList1DataSource = list;
thisDropDownList1DataTextField = "Name";
thisDropDownList1DataValueField = "ID";
thisDropDownList1DataBind();
}
以上就是关于c#的泛型,委托,反射是什么全部的内容,包括:c#的泛型,委托,反射是什么、关于如何学好java!、C#泛型如何提高性能的等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)