相关文章推荐
狂野的人字拖  ·  如何将excel ...·  8 月前    · 
博学的黄瓜  ·  ios14拍照怎么连拍-掘金·  1 年前    · 
乐观的火锅  ·  借助Calibre ...·  1 年前    · 

当批量处理一些数据的时候,经常会将生成的对象放入集合中,这时候很容易犯一个错误,就是将已经放入集合中的对象修改部分属性后,又重新放入这个集合,表面上看是将一个新的对象放入集合中,实际上原来集合中的对象的属性已经被修改了。因为集合中存放的是对象的引用,改变原来对象的属性,那么从集合中得到的对象属性也就变了。下面一个示例就是这个问题

monitorCompanyRiskGradeTrend = new MonitorCompanyRiskGradeTrend();
				monitorCompanyRiskGradeTrend.setId(UUIDUtils.getUUID());
				monitorCompanyRiskGradeTrend.setAccountId(accountId);
				monitorCompanyRiskGradeTrend.setCompanyName(monitorCompanyRisk.getCompanyName());
				monitorCompanyRiskGradeTrend.setRiskGrade(monitorCompanyRisk.getRiskGrade());
				monitorCompanyRiskGradeTrend.setCycle("1");
				monitorCompanyRiskGradeTrend.setReportDate(calTrend.getTime());
				monitorCompanyRiskGradeTrend.setCreateTime(calTrend.getTime());
				monitorCompanyRiskGradeTrendList.add(monitorCompanyRiskGradeTrend);
				if(1 == calTrend.get(Calendar.DAY_OF_MONTH)){
					monitorCompanyRiskGradeTrend.setId(UUIDUtils.getUUID());
					monitorCompanyRiskGradeTrend.setCycle("3");
					monitorCompanyRiskGradeTrendList.add(monitorCompanyRiskGradeTrend);
				if(2 == calTrend.get(Calendar.DAY_OF_WEEK)){
					monitorCompanyRiskGradeTrend.setId(UUIDUtils.getUUID());
					monitorCompanyRiskGradeTrend.setCycle("2");
					monitorCompanyRiskGradeTrendList.add(monitorCompanyRiskGradeTrend);

从表面上看没有逻辑问题,因为数据库中id是主键,那么重新生成主键再存入是没问题的,但是在保存数据的时候就报有重复主键,关键就是因为集合中存储的是对象的引用,重复将同一个对象的引用添加到集合中,保存数据的时候就出现了重复项了。

通过以下代码我们可以清晰的理解这个问题

import java.util.ArrayList;    
import java.util.List;    
public class Test5 {    
    public static void main(String args[]){    
        List<User> userList1 = new ArrayList<User>();           
        List<User> userList2 = new ArrayList<User>();       
        User user1 = new User();    
        userList1.add(user1);           
        userList2.add(user1);    
        System.out.println("SET VALUE FOR USERLIST2:");         
        for(User user: userList2){    
            user.setName("name");    
            user.setPassword("password");           
        System.out.println("PRINT VALUE FOR USERLIST1:");    
        for(User user: userList1){    
            System.out.println(user.getName());             
            System.out.println(user.getPassword());             
    public static class User{    
        private String name;    
        private String password;    
        public String getName() {    
            return name;    
        public void setName(String name) {    
            this.name = name;    
        public String getPassword() {    
            return password;    
        public void setPassword(String password) {    
            this.password = password;
示例描述:本章演示如何开始使用JDK进行程序的开发。
HelloWorldApp.java    第一个用Java开发的应用程序。
firstApplet.java     第一个用Java开发的Applet小程序。
firstApplet.htm     用来装载Applet的网页文件
示例描述:本章介绍开发Java的基础语法知识。
  accumulationByDoWhile.java  用do~while语句写的累加程序
  accumulationByFor.java   用for语句写的累加程序
  accumulationByWhile.java   用while语句写的累加程序
  boolExample.java    演示boolean变量的程序
  charExample.java    演示char变量的程序
  compare.java     演示前缀、后缀自加之间区别的程序
  constCharExample.java   演示转义字符
  converseNumber.java    逆向输出数字
  daffodilNumber.java    求水仙花数
  division.java     演示整除结果
  errorCompoundVariable.java  错误使用局部变量示例
  factorial.java     求阶乘
  Fibonacci.java     求Fiblnacci数列
  GcdAndGcm.java    求最大公约数和最小公倍数
  errorInit.java     演示变量初始化错误的程序
  integerExample.java    演示各种整型变量的使用
  isPrime.java      判断素数
  leapYearByIf.java    用if语句判断闰年
  leapYearByLogical.java   用逻辑表达式判断闰年
  lowToUpper.java     小写字母转换成大写字母
  lozengeStar.java     输出一个由*组成的菱形
  multiplyTable.java    求乘法口诀表
  narrowingConversion_1.java  缩减转换引发错误示例1
  narrowingConversion_2.java  缩减转换引发错误示例2
  notMultipleOfThree.java   把100-200之间不能被3整除的数输出
  outputByDoWhile.java   用while循环随机输出数据
  outputByWhile.java    用do~while循环随机输出数据
  outputMax.java     求两个数中的最大数
  overflowExample.java   演示溢出
  precedence.java     演示自加运算符的优先级
  primeNumber.java    输出100-200之间的所有素数
  ranking.java      评定成绩等级
  rankingBySwitch.java    用switch语句评定成绩等级
  realExample.java     演示浮点数的有效位数
  remainder.java     取余运算示例
  showBreak.java     利用标号语句跳转出所有循环嵌套
  showCount.java     循环计数示例
  showDoubleLoop.java   演示双重循环
  showDoubleLoopSe.java   改进的双重循环
  showOrder_1.java    演示操作数求值顺序示例1
  showOrder_2.java    演示操作数求值顺序示例2
  sign.java      用条件运算实现符号函数示例
  signByIF.java     用if语句实现符号函数示例
  triangleStar.java     输出一个由*组成的直角三角形
  upperToLowCase.java   大写转换成小写
  variableScopeExample.java  变量使用范围示例
示例描述:本章学习对象和类。
  accessMember.java    访问成员变量示例
  constructNoPara.java    无参数的构造方法
  constructWithPara.java   带参数的构造方法
  declareDefault.java    缺省访问权限的使用
  declarePrivate.java    私有访问权限的使用
  declareProtected.java    保护访问权限的使用
  deriveClass.java     子类访问父类变量示例
  getLinePara.java     获取命令行参数示例
  hasStaticMethod.java    静态成员方法示例
  hasStatMember.java    静态成员变量示例
  HelloNative.c     用C写的一个小程序
  HelloNative.dll     用C生成的DLL文件
  HelloNative.exp     用VC编译生成的辅助文件
  HelloNative.h     用javah生成的C语言用的头文件
  HelloNative.java     准备调用C函数的java文件
  HelloNative.lib     用VC编译生成的静态库文件
  HelloNative.obj     用VB编译生成的目标文件
  HelloNativeTest.java    测试本地化是否成功的类文件
  instanceVar.java     定义一个实例成员变量
  invokeByObject.java    对象实参传递示例程序
  invokeByValue.java    传值调用示例程序
  invokeMethod.java    同一个类中调用方法示例
  invokeOther.java     类的外部调用方法示例
  invokeStaticMethod.java   调用静态方法示例
  localVariable.java    演示局部变量
  localVSmember.java    局部变量与成员变量同名问题示例
  onlyTest.java     对象传值示例
  otherClass.java     从类的外部访问对象的成员
  showInstVar.java     演示不同的对象拥有不同的成员变量
  showMain.java     演示main方法访问本类成员
  showMethod.java    演示如何定义一个方法体
  showReturn_1.java    return语句示例1
  showReturn_2.java    return语句示例2
  showStaicVar.java    演示静态变量的使用
  staticBlock.java     演示静态块的使用
  staticVar.java     定义静态变量
  supplyTest.java     对象作为静态成员使用示例
  trySwap.java     试图交换两个形参的值
  useOnlyTest.java     创建多个对象,演示this的作用
  useStaticBolck.java    使用静态块
  useStVar.java     使用静态成员变量
示例描述:本章学习继承与多态。
  absClass.java     抽象类定义示例
  ancestor.java     基类定义示例1
  ancestor_1.java     另一个基类定义
  anonymousInner.java    匿名内部类
  base.java      定义一个基类
  BaseColors.java     一个简单的接口
  basePoint.java     一个测试用的基类
  Colorable.java     一个子接口
  ColoredPoint.java    一个测试用子类
  common.java     一个公用类
  derive.java      一个测试用子类
  differ.java      测试静态方法与实例方法之间的区别
  forefather.java     一个简单的基类
  grandson.java     上面这个类的子类
  hasConstructor.java    拥有构造器的类
  hasFinalFun.java     拥有最终方法的类
  hasRecall.java     可以完成回调功能的类
  HasStatic.java     一个简单的拥有静态成员的类
  hideMember_1.java    成员隐藏示例1
  hideMember_2.java    成员隐藏示例2
  hideMember_3.java    成员隐藏示例3
  hideMember_4.java    成员隐藏示例4
  hideMember_5.java    成员隐藏示例5
  implementABS.java    继承一个抽象类
  impRecall.java     实现回调函数
  inheritConstruct_1.java   构造器继承示例1
  inheritConstruct_2.java   构造器继承示例2
  inheritConstruct_3.java   构造器继承示例3
  inheritConstruct_4.java   构造器继承示例4
  inheritConstruct_5.java   构造器继承示例5
  inheritConstruct_6.java   构造器继承示例6
  inheritor.java     子类覆盖父类示例
  inPack.java      包示例
  LotsOfColors.java    定义一个子接口
  matching.java     重载解析示例
  notInPack.java     用前缀引用包中的类
  onlyShow.java     一个简单的接口
  Outer_1.java     外部类示例1
  Outer_2.java     外部类示例2
  Outer_3.java     外部类示例3
  Outer_4.java     外部类示例4
  Outer_5.java     外部类示例5
  Outer_6.java     外部类示例6
  Outer_7.java     外部类示例7
  Outer_8.java     外部类示例8
  overrideMember_1.java   成员方法覆盖示例1
  overrideMember_2.java   成员方法覆盖示例2
  overrideMember_3.java   成员方法覆盖示例3
  overrideMember_4.java   成员方法覆盖示例4
  overrideMember_5.java   成员方法覆盖示例5
  Paintable.java     实现了多个接口的方法
  PaintedPoint.java    实现了多个接口的方法
  Point.java      一个简单的类
  PrintColors.java     一个子接口
  RainbowColors.java    一个子接口
  realPoint.java     一个子类
  second.java      属于一个命名包的类
  showDiff.java     演示隐藏与覆盖之间的区别
  showSomething.java    测试运行时多态
  stupid.java      试图覆盖最终方法的类,它有错误
  Sub.java      一个简单的子类
  Super.java      一个基类
  testOverload.java    测试方法的重载示例1
  testOverload_1.java    测试方法的重载示例2
  testOverload_2.java    测试方法的重载示例3
  testOverload_3.java    测试方法的重载示例4
  useConstructor.java    使用构造器
  useHideMember_2.java   试图使用隐藏的成员变量
  useInner.java     使用内部类
示例描述:本章学习数组与字符串。
  ArrayString.java     字符串数组
  assignTwoDime.java    为二维数组赋值
  getMaxElem.java    获取数组中的最大元素
  incCapicity.java     演示StingBuffer的容量增长
  SortDemo.java     排序示例
  travelTwoDime.java    遍历二维数组
  traversing.java     遍历一维数组
  useStrBuf.java     使用StringBuffer示例
  useString.java     使用String示例
  YanghuiTri.java     构造和显示杨辉三角
示例描述:本章学习Java的异常处理。
  demoException_1.java   异常示例1
  demoException_2.java   异常示例2
  demoException_3.java   异常示例3
  demoException_4.java   异常示例4
  demoException_5.java   异常示例5
  divZeroError.java    除零异常
  hasCheckException.java   检查型异常
  MyException.java    用户自定义异常
  myInput.java     输入数据示例
  nestException_1.java    异常嵌套示例1
  nestException_2.java    异常嵌套示例2
  nestException_3.java    异常嵌套示例3
  outBoundError.java    下标越界异常
  throwException.java    抛出异常示例
  throwsException.java    声明抛出异常
  useMyException.java    使用自定义异常
示例描述:本章学习Java的输入和输出。
  CopyFile.java     文件复制实例
  dir.java       显示目录下的所有文件和目录
  encrypt.java      文件加密
  FileList.java     自己实现的一个文件名称枚举类
  MyDataIO.java     数据输入输出示例
  MyFileOutput.java    将键盘读入的文字保存到文件
  MyPipedIO.java     管道流示例
  MySequenceIn.java    顺序输入流示例
  ObjectFileTest.java    序列化对象示例
  ReadAndWrite.java    读入和写出数据
  ReadAndWriteFile.java   读入数据写出到文件
  Student.java      定义一个用来序列化的类
  ThreadIn.java     接收数据用的线程类
  ThreadOut.java     发送数据用的线程类
  TypeFile.java     显示文件内容的类
  useScanner.java     用Scanner接收用户的输入
示例描述:本章学习多线程。
  enhanceThread.java    一个自己定义的增强型线程类
  ThreadImRunnable.java   继承Runnable接口实现多线程
  mulThread.java     创建多个线程对象的类
  demoJoin.java     演示使用join()以确保主线程最后结束
  clicker.java      一个计数用的线程类
  demoPri.java     调用上面这个类设置线程优先级示例
  myThread.java     自己定义的一个Thread的子类
  mutexThread.java    一个能管理临界区的线程类
  demoMutex.java     使用上面这个类来演示线程的互斥
  commSource.java    一个共享资源的类
  demoSynchrony.java    演示线程的同步
  setDataThread.java    设置数据的线程类
  readDataThread.java    读取数据的线程类
  demoEnhanceThread.java   使用自己定义的线程类示例
  producer_consumer.java   演示生产者-消费者线程
  consumer.java     消费者线程
  producer.java     生产者线程
  common.java     公有类
示例描述:本章学习运行时类型识别。
  Candy.java      一个用来测试的简单类
  changeFields.java    改变属性值示例
  Circle.java      一个用于测试的简单类
  DumpMethods.java    使用反射机制来获取类中的方法
  getClassName.java    利用反射机制获取类的名字
  invokeConstructor.java   利用反射机制调用构造器
  invokeMethod.java    利用反射机制调用成员方法
  listConstructors.java    利用反射机制获取构造器列表
  listFields.java     利用反射机制获取成员属性列表
  listMethods.java     利用反射机制获取成员方法列表
  loadClass.java     动态装载一个类
  Shape.java      一个用于测试的简单类
  useArray1.java     用反射机制使用数组示例1
  useArray2.java     用反射机制使用数组示例2
示例描述:本章学习泛型。
  demoBounds.java    演示有界类型
  demoForceChange.java   演示强制类型转换
  demoGeneric.java    泛型类的使用示例
  demoGenIF.java     测试泛型类
  demoGenMethods.java   泛型方法示例
  demoHerit_1.java    泛型类继承示例1
  demoHerit_2.java    泛型类继承示例2
  demoRTTI_1.java    泛型类的类型识别示例1
  demoRTTI_2.java    泛型类的类型识别示例2
  demoWildcard.java    通配符使用示例
  demoWipe.java     擦拭示例
  derivedGen.java     泛型父类继承示例
  derivedNonGen.java    非泛型父类继承示例
  foo.java      一个有错误的类
  Gen.java      无限界的泛型擦拭
  Generic.java     一个简单的泛型类
  genMethod.java     一个泛型方法
  GenStr.java      有限界的泛型擦拭
  MinMax.java     泛型接口示例
  MyClass.java     实现一个泛型接口
  nonGen.java     以非泛型类为父类
  simpGen.java     使用泛型类示例
  Stats.java      一个有界类泛型
  superGen.java     父类是泛型
  twoGen.java     有两个参数的泛型类
示例描述:本章学习集合。
  CompareScore.java    实现比较器接口
  demoAlgorithm.java    集合中简单算法示例
  demoArrayList.java    链表使用示例
  demoBinSearch.java    二分查找示例
  demoEnumSet.java    枚举类型示例
  demoHashMap.java    哈希映射示例
  demoHashSet.java    哈希集合示例
  demoSort.java     排序示例
  demoTreeMap.java    树映射示例
  demoTreeSet.java    树集合示例
  demoVector.java     向量使用示例
  job.java      模拟操作系统的进程调度
  monkey.java     用链表求猴子选大王
  myCompare.java     自己实现的比较器接口
  reverseString.java    利用栈将字符串逆序输出
  scheduling.java     模拟操作系统的作业调度过程
  showClothValue.java    根据用户输入型号输出相应的价格
  Size.java      一个枚举类
  Student.java      用于记录学生信息的类
示例描述:本章学习类型包装器、自动装箱和元数据。
  demoAnno.java     给方法做注释示例
  demoAutoBox_1.java    自动装/拆箱机制示例1
  demoAutoBox_2.java    自动装/拆箱机制示例2
  demoAutoBox_3.java    自动装/拆箱机制示例3
  demoInteger.java     整数类型包装器使用示例
  demoSingle.java     单成员注释使用示例
  DeprecatedClass.java    Deprecated注释示例
  InProgress.java     Documented元注释使用示例
  Marker.java      一个被注释的接口
  Meta.java      利用反射机制获取方法的注释
  MetaAll.java     获取所有注释示例
  MyAnno.java     包含了默认值的注释
  MyMarker.java     标记注释使用示例
  MySingle.java     单成员注释使用示例
  OverrideTester.java    Override注释示例
  SuppressWarningsTester.java  SuppressWarnings注释示例
  TODO.java      Target元注释使用示例
  What.java      显示全部注释
示例描述:本章学习常用工具类。
  checkEmail.java     利用正则表达式检验Email的合法性
  currentTime_1.java    显示时间示例程序1
  currentTime_2.java    显示时间示例程序2
  currentTime_3.java    显示时间示例程序3
  DateAndTime.java    用Calendar显示当前的日期和时间
  demoFmtTime.java    使用时间格式转换符输出日期和时间
  demoFormatter.java    Formatter简单输出示例
  demoGroup.java     组匹配使用示例
  demoMathing.java    匹配方法使用示例
  demoMemory.java    内存管理示例程序
  demoPattern_1.java    Pattern使用示例1
  demoPattern_2.java    Pattern使用示例2
  demoRandom.java    产生随机数序列示例
  demoReplace.java    替换方法使用示例
  demoRound.java     取整函数使用示例
  elapsed.java      计算程序运行时间
  exitJVM.java     从子线程中退出虚拟机
  getPI.java      利用随机数求π值
  progPI.java      利用反正切函数求π的值
  runNotepad.java     启动记事本
  showCalendar.java    用GregorianCalendar实现一个万年历
  showProperties.java    获取环境属性
  textToTime.java     从文本串创建日期对象
  useLog.java      利用换底公式求任意对数值
示例描述:本章学习GUI程序设计。
  addNodeInJTree.java    在JTree中增加节点示例
  AlarmClock.java     小闹钟程序
  AWTComponents.htm   为显示AWT组件而编制的网页文件
  AWTComponents.java   AWT组件示例
  AWTFrame.java     用AWT编写的一个简单窗口
  CheckAchromatopsiat.java   色盲检测程序
  demoBorderLayout.java   边框布局使用示例
  demoCardLayout.java    卡片布局使用示例
  demoGridBagLayout.java   增强网格布局使用示例
  demoGridLayout.java    网格布局使用示例
  demoJApplet.htm    运行JApplet的网页文件
  demoJApplet.java    JApplet使用示例
  demoJButton.java    按钮使用示例
  demoJCheckbox.java    复选框使用示例
  demoJComboBox.java   组合框使用示例
  demoJDialog.java    对话框使用示例
  demoJFrame.java    JFrame简单使用示例
  demoJLabel_1.java    图像标签使用示例
  demoJLabel_2.java    改变标签上鼠标形状示例
  demoJList.java     列表框使用
  demoJMenu.java     菜单使用示例
  demoJPanel.java     面板使用简单示例
  demoJRadioButton.java   单选按钮使用示例
  demoJScrollPane_1.java   在JScrollPane创建时添加组件示例
  demoJScrollPane_2.java   通过add()方法添加组件示例
  demoJSplitPane_1.java   分隔板简单示例1
  demoJSplitPane_2.java   分隔板简单示例2
  demoJTabbedPane.java   选项板使用示例
  demoJTable_1.java    表格使用示例1
  demoJTable_2.java    表格使用示例2
  demoJTable_3.java    表格使用示例3
  demoJTable_4.java    表格使用示例4
  demoJTable_5.java    表格使用示例5
  demoJText.java     文本框和密码框使用示例
  demoJTextArea.java    文本区使用示例
  demoJToolBar.java    工具栏使用示例
  demoJTree.java     创建JTree示例
  ExampleFileFilter.java   Sun公司提供的一个文件名过滤器
  findDialog.java     查找对话框
  fontDialog.java     字体选择对话框
  MyTableModel.java    本类实现了一个表格用的模型,取代默认的模型
  Notebook.java     记事本
  painting_1.java     在面板上画出简单图形示例1
  painting_2.java     在面板上画出图形示例2
  reMulEvent.java     响应单击按钮事件
  showTriDialog.java    用系统预定义的对话框
本章下面还有一些编程要用到的图片和声音文件,不一一列出。
示例描述:本章学习多媒体程序设计。
  building.java     调用另外一个houseCanvas类画出一栋房子
  CombinerCanvas.java    编写自己的画布,所要显示的图片在此画布上显示
  CombinPic.java     合成两幅图片
  DrawArcs.java     画椭圆和圆弧示例
  DrawLines.java     画直线示例
  DrawPoly.java     画多边形示例
  DrawRects.java     画矩形示例
  fadeInOut.java     淡入淡出效果示例
  FillArea.java     填充图形示例
  FontsCanvas.java    自行管理字体的画布
  GetFonts.java     获取系统中安装的字体示例
  GrayFilter.java     自己实现的GrayFilter类
  GrayModel.java     实现一个具备灰度变换功能的Model
  houseCanvas.java    用直线画出一栋房子
  illumination.java     光照特效示例
  LightingLiteral.java    字体特效显示示例
  ManageFonts.java    自行管理字体示例
  mixing.java      显示色彩混合效果
  playAudio.java     在Application中播放声音文件
  playMP3.java     增强的声音播放文件
  playMusic.htm     可以播放背景音乐的一个网页
  playMusic.java     利用AudioClip播放声音文件
  playVideo.java     媒体播放器编写示例
  ResizeOval.java     缩放图形示例
  ShowFonts.java     建和使用字体示例
  SoundBase.java     将Java Sound API封装在一个线程中
  TransparencyExample.java   为实现色彩混合效果而定义的画布
  viewPic.java     用标签显示图像示例
本章下面还有一些编程要用到的图片和声音文件,不一一列出
示例描述:本章学习数据库程序设计。
  AddressList.java     学生信息管理系统实例
  deleteData.java     从数据库中删除记录
  FirstExample.mdb    本章用到的数据库文件
  insertData.java     向数据库中添加新数据
  queryData.java     查询数据示例
  updateData.java     修改数据示例
示例描述:本章学习C/S网络程序设计。
  chatClient.java     聊天客户端程序
  chatServer.java     聊天服务端程序
  Client.java      一个简单的客户端程序
  DownFile.java     文件下载示例
  GetHostName.java    根据IP查找主机名
  GetIP.java      根据域名查找IP地址
  GetMyIP.java     获取本机IP地址
  MultiServer.java     可以响应多个客户端的服务程序
  myBrowser.java     一个简单的浏览器
  Server.java      一个简单的服务端程序
  ServerThread.java    一个服务端的线程类
  UDPChat.java     用UDP实现的聊天程序示例
示例描述:本章学习JSP程序设计。本章所有文件均已经按照Tomcat网站部署的要求放置在各自的目录下,然后打包成ZIP文件。读者只需要解包后放置在某一分区中,然后在Tomcat中配置好入口就可以使用。
下面的文件均放置在ROOT目录下面
  ArbitraryObject.java    实现一个事件监听者接口的类
  calendar.jsp      用JSP实现的日历
  count.txt      站点计数器保存的数据文件
  counter.jsp      用JSP实现的计数器
  faq.java      连接数据库用的JavaBean
  leaveword.htm     留言板的主页面
  Model.java      自己定义的事件源类
  ModelChangedListener.java  自己定义的一个事件监听者接口
  MouseMovedExampleEvent.java 事件状态对象示例
  MouseMovedExampleListener.java 鼠标事件监听者接口与事件监听者示例
  OurButtonCustomizer.java   实现一个“按钮”Beans的定制器
  query.jsp      数据库查询程序
  saveword.java     用于保存记录的JavaBean
  saveword.jsp     后台保存数据的JSP文件
  viewword.jsp     查看留言的JSP页面
  WeekDayBeanInfo.java   实现BeanInfo接口示例
  WeekDayEditor.java    实现属性编辑器接口
下面的文件均存放在chat目录下,是聊天室的组成文件。
  chatreg.java      用户注册用到的JavaBean文件
  chatreg.jsp      用户注册的前台JSP文件
  chatregcof.jsp     用户注册检查JSP文件
  chatroom.jsp     聊天室的主页面
  confirm.jsp      检查登录是否正确的JSP文件
  in.jsp       即将进入聊天室前的提示页面
  listuser.jsp      显示聊天室内的所有用户名的JSP文件
  logout.jsp      清除用户的相关信息
  netchat.jsp      用户进入聊天室的界面文件
  showmsg.jsp     显示各个用户所说的话
  talk.jsp       用户聊天用的JSP文件
示例描述:本章是一个IM软件的完整代码。
  ChatFrame.java     聊天用的主界面程序
  ClientManageFrame.java   是好友管理窗口,也是客户端程序的主窗口
  DBConnection.java    连接数据库用的JavaBean
  FindUserDlg.java    查找好友对话框
  FindUserInfo.java    显示用户基本信息
  FriendLabel.java     在list列表中显示用户的头像和字符信息
  Login.java      用户登录界面
  LoginUser.java     定时器的任务类,用于定时获取上线的用户的信息
  MyInfo_AboutBox.java   显示作者信息
  ReceiveOthersDialog.java   当用户收到陌生人的消息时,这个类向用户提示
  RegisterDialog.java    用户注册面板
  Server.java      提供各种服务的类
  ServerFrame.java    服务器端的主界面
  ServerThread.java    与客户端通讯的线程
  SetCenter.java     将窗口设置在屏幕中央的类
  showTimeTask.java    刷新时间的类
  StartServer.java     启动服务器的主类
  UpdateDialog.java    更新用户信息的对话框
  UserInfo.java     获取用户信息的类
  UserInfoBean.java    保存用户信息的一个JavaBean
                                    int和Integer有什么区别?
  答:int是java的原始数据类型,Integer是java为int提供的封装类,java为每个原始数据类型都提供了封装类。
String和StringBuffer的区别?
  答:String是不可变的对象,每次对String类型进行改变都相当于产生了一个新的对象,StringBuffer是可变的字符序列,所以如果要经常改变某个字符串的话建议使用StringBuffer。
list、set、map问题?
  答:set    不允许重复,无序
         list   允许重复,有序
         map    成对的数据结构,键值必须具有唯一性
Servlet和CGI的区别?
  答:Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式允许其service方法,一个实例可以服务于多个请求,并且其实例一般不会被销毁,而CGI对每个请求都产生新的进程,服务完后就销毁,所以效率上低于Servlet。
面向对象的特征?
  答:1:封装:通过定义类并且给类的属性和方法加上访问控制
         2:继承:子类继承父类,子类可以拥有父类中已定义的方法,并且子类可以修改父类中的方法使其更适合特殊需求。
         3:多台:不同对象对统一消息作出不同响应称之为多态
         4:抽象:忽略与当前主题无关的那些方面,将注意力集中在与当前目标有关的方面
运行时异常和一般异常有何异同?
  答:运行时异常时(JVM)java虚拟机在运行过程中发生的问题,比如:内存溢出等问题。这类异常没法要求程序员去一一捕获并抛出,一般异常是Java类库或程序员自己写的代码发生的错误,这类异常可以由我们去一一捕获并抛出。
多线程几种实现方法,同步?
  答:多线程有两种实现方法,一种是继承Thread类或者实现Runnable接口。同步就是在方法返回类型后面加上synchronized。
c#中的委托,事件是不是委托?
  答:委托就是将方法作为一个参数带入另一个方法叫做委托,事件是一种特殊的委托。
应用程序域?
  答:应用程序域可以理解为一种轻量级的进程,起到安全的作用,占用资源小。
Class.forName作用?
  答:调用该访问返回一个以字符串指定类名的类对象。
  答:JDO是java对象持久化的新的规范,为java data object的简称,也是一个用于存取某种数据仓库中的对象的标准化API。
CORBA?
  答:CORBA标准是公共对象请求代理结构,用途为:用不同的程序设计语言书写,在不同的进程中运行,为不同的操作系统开发。
xml解析技术?
  答:常用的DOM、SAX等
         DOM:处理大型文件时性能下降的非常厉害,适合对xml的随机访问
         SAX:事件驱动型的xml解析方法,适合对xml的顺序访问
jsp常用动作?
  答:jsp:include    引入一个文件
         jsp:useBean    实例化JavaBean
         jsp:setProperty    设置JavaBean属性
         jsp:getProperty    输出JavaBean属性
         jsp:forward    转发
CTS、CLS、CLR分别作何解释?
  答:CTS    通用类型系统、CLS    通用语言规范、CLR    公共语言运行时。
Struts1和Struts2原理和区别?
  答:Struts1和Struts2是两个完全不同的框架,Struts1以ActionServlet作为核心控制器,由ActionServlet负责拦截用户的所有请求。Struts2以核心控制器FilterDispatcher为基础,包含了框架内部的控制流程和处理机制。
Hibernate工作原理,Hibernate数据持久化?
  答:Hibernate工作原理:
         1:读取并解析映射信息,创建SessionFactory
         2:打开Session
         3:创建事物
         4:持久化操作
         5:提交事务
         6:关闭Session
         7:关闭SessionFactory
         Hibernate持久化:Hibernate根据定义的映射规则将对象持久化保存到数据库,这就实现了对象的持久化。
Spring由那几个模块组成?
  答:Spring主要由7个模块组成:
         1:Spring核心容器:提供了Spring框架的基本功能
         2:Spring AOP:通过配置管理特性
         3:Spring ORM:Spring框架集成了若干ORM框架
         4:Spring DAO:打开关闭数据库连接
         5:Spring WEB:为基于WEB服务的应用程序提供上下文服务
         6:Spring Context:向Spring框架提供上下文信息
         7:Spring MVC:分离模型、视图、控制器、以便更容易定制
折构函数和虚函数?
  答:折构函数式销毁一个类的函数,虚函数是为了C++的动态绑定而设计的。
描述你的编程风格?
  答:类名首字母大写,常量一般全部大写,给自己的代码加注释。
控制流程?
  答:控制流程一般使用if判断条件。有第二分支,多分支,循环结构。循环本质上也是通过判断来实现的。
多形与继承?
  答:多形:一个类中多个同名方法。继承:子类继承父类。
jsp内置对象?
  答:request    用户端请求
         response    回应
         pageContext    网页属性
         session    会话
         out    输出
         page   当前网页
         exception    错误网页
         application    servlet正在执行的内容
         config    servlet构架部件
Struts模型驱动?
  答:封装请求参数。
简述JDBC?
  答:JDBC数据库连接,是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问。
什么情况下不建议使用Hibernate?
  答:当数据量大,并且表关系复杂的时候不建议使用。
sleep()和wait()有什么区别?
  答:sleep()是线程类的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但监控状态依然保持,到时候会自动恢复。
         wait()是Object类的方法,对此对象调用了wait方法导致本线程放弃对象锁,进入等待锁定池,只有针对此对象发出notify方法后本线程才进入对象锁定池准备获得对象锁进入运行状态。
同步和异步,在什么情况下分别使用?
  答:如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
         当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步。在很多情况下采用异步往往更有效率。
数据库三大范式?
  答:1:确保每列都是不可分割的原子值
         2:确保每列都和主键相关
         3:确保每列都和主键直接相关,而不是间接相关
单例模式有哪些好处?
  答:单例模式是一种比较常见的设计模式,带给我们以下好处:
         1:控制资源的使用
         2:控制实例的产生数量
         3:让多个不相关的两个线程或进程之间实现通信
为什么要用spring?
  答:1、主要将各个框架有效的联系起来,缩短实际编程时间。
         2、可以将各个框架进行有效的管理和控制,让数据传输安全。
spring的IOC和DI?
  答:控制反转和依赖注入是spring的两大基础作用。主要是将所有组件在spring提供的外部容器中加载。提高安全性,减低耦合性,使各个框架或者类之间的依赖性降低。
什么是声明式的事务管理?为什么要用?spring如何实现声明式的事务管理?
  答:声明式的事务管理主要是将在进行对数据库中数据的添加或者修改时需要执行事务管理,主要是为了避免在执行添加或修改的时候添加或修改不完全正确,导致数据丢失。spring使用AOP面向切面的思想进行事务管理的。
spring和Hibernate继承后,定义事务管理特性的时候查询为什么要定义为read-only?
  答:因为添加、删除和更新都涉及到了数据库的修改,而查询并未涉及到数据库修改,所以只需要定义只读,这样可以提高效率,进行更加方便的事务管理。
请你谈谈对Hibernate OR映射的理解?
  答:将数据库中的每一张表都映射成一个实体。
配置了lazy="true"一定会懒加载吗?
  答:不一定,如果在配置中你也使用了fetch属性的话此时lazy就会失效。
Hibernate数据库标识与主键之间的认识?
  答:标识是为了方便和简介映射文件,主键是为了让数据不会重复。
为什么每次请求都要创建一个Action对象?
  答:Struts2每次请求的时候都会创建一个action实例,这样会保证线程的安全。Struts1只是在第一次请求的时候创建一个action实例,以后每次相同的请求都直接从内存中去读取,它是单例模式,安全性较差。
Struts2是如何实现MVC模式的?
  答:在Struts2里面是将每次页面的请求进行处理,然后将请求需要输出的数据转发到需要做数据显示的页面。Struts2只是起到一个数据接收和转接的功能,就是Controller控制器,而传来数据的页面叫view显示层,Struts2将数据提交给进行处理的类叫Model模型层,专门进行数据处理和数据库的连接。
heap和stack有什么区别?
  答:栈是一种线形集合,其添加和删除元素的操作应在同一段完成,栈按照后进先出的方式进行处理。堆是栈的一个组成元素。
EJB和JavaBean的区别?
  答:EJB不是一般的JavaBean,EJB是企业级的JavaBean,EJB一共分为3种,实体Bean,消息Bean,会话Bean。书写EJB要遵循一定的规范,另外要运行EJB,你需要有相应的EJB容器,比如WebLogic、jboss等,而JavaBean不需要,只需要安装Tomcat就可以了。EJB用于服务端的应用开发,而JavaBean用于客户端应用开发。
  答:触发器是一种特殊的存储过程,主要通过事件来触发而被执行。
什么是存储过程?用什么调用?
  答:存储过程是一个预编译的SQL语句,优点是允许模块化的设计。就是说只需要创建一次,以后再程序中就可以调用多次。使用存储过程比单纯的SQL语句要快,可以用一个命令对象来调用存储过程。
索引优缺点?
  答:索引可以提高对数据库中数据的检索,缺点是减慢了数据录入速度,同时也增加了数据库的尺寸大小。
什么是事务?什么是事锁?
  答:事务就是被绑定在一起,作为一个逻辑单元执行的SQL语句。如果任何一个操作失败,那么整个就失败。共同失败或共同成功。锁可以保证事务的完整性和并发性。
什么是视图?游标是什么?
  答:视图是一种虚拟的表,具有和物理表相同的功能。游标是对查询出来的结果集作为一个单元来有效的处理,可以对结果集的当前行做修改。
select执行顺序?
  答:from
         where
         group by
         having
         select
         order by
Collection和Collections的区别?
  答:Collection是集合类的父类,继承它的主要由set和list
         Collections是针对集合类的帮助类,它提供了一系列针对集合的搜索,排序,线程安全化等操作。
final、finally、finalize的区别?
  答:final用于声明属性方法和类,分别表示:属性不可变,方法不可覆盖,类不可继承。
         finally是异常处理语句的一部分,表示总是执行。
         finalize是Object的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法。
assert是什么?什么时候用到?
  答:断言,可以将断言看成是异常处理的一种高级形式,可以用来判断某个特定的表达式或值是否为真。
接口是否可以继承接口?抽象类是否可以实现接口?抽象类是否可以继承实体类?
  答:接口可以继承接口,抽象类可以实现接口,抽象类可以继承实体类。
引用传递和值传递?
  答:引用传递:形参改变影响实参
         值传递:形参改变不影响实参
当一个线程进入一个对象的synchronized方法后,其他线程是否可进入此对象的其他方法?
  答:其他方法前是否加了synchronized关键字,如果没加则能。
说出servlet生命周期?
  答:servlet实例化时调用init方法,得到请求时调用service方法,service方法自动派遣doget或dopost方法,最后当实例销毁时调用destroy方法。
error和exception有什么区别?
  答:error是指错误,通常程序员不能通过代码来解决。底层环境或硬件问题。
         exception是指异常,可以通过代码来解决的问题。
forward和redirect的区别?
  答:forward是转发,浏览器跳转后不显示新的地址。
         redirect是重定向,浏览器跳转后显示新的地址。
         对比之下forward更加高效,并且它有助于隐藏实际地址,但是有些情况则必须使用redirect,否则会报异常。
jsp中动态include和静态include的区别?
  答:动态include用jsp:include实现,适用于动态页面,可以携带参数
         静态include用include伪码实现,适用于静态页面
math.round(11.5)等于多少?math.round(-11.5)等于多少?
  答:Math.round()对数字进行四舍五入
         Math.round(11.5)=12
         Math.round(-11.5)=11
String s=new String("xyz");创建了几个String Object?
  答:创建了两个String对象一个保存的引用地址,一个保存实际的值。
数组有没有length()这个方法?String呢?
  答:数组里面没有length()方法,而是length属性。String有length()这个方法。
swtich()能否作用在byte、long、String上?
  答:swtich()传递的应该是一个整数表达式,所以它的值只能是:int、short、char、byte所以long和String都不能作用在swtich()上。
jsp和servlet之间的联系?
  答:jsp前段动态页面,servlet是纯java类
         jsp被编译之后会转换为servlet执行
java基本数据类型有哪些?String是不是基本数据类型,他们有何区别?
  答:基本数据类型8种:int、short、byte、long、float、double、char、boolean
         String不是基本数据类型,引用数据类型。
         区别:基本数据类型比较实用“==”,引用数据类型实用equest,并且引用数据类型存放的是地址而不是具体的值。
写一个方法,实现字符串的替换,如:输入bbbwlirbbb,输出bbbhhtccc?
  答:String s="bbbwlirbbb";
         s.replaceAll("wlirbbb","hhtccc");
如何将数值型字符转换为数字(Integer,Double)?
  答:可以用Integer.parseInt()和Double.parseDouble()方法
如何将数字转换为字符?
  答:可以使用String的valueOf()方法。
如何取得1970到现在的毫秒数?
  答:可以用getTime()方法。
如何格式化日期?
  答:可以用SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
判断是否有子文件?判断是否有子目录?判断文件是否存在?
  答:判断是否有子文件使用file.isFile()
         判断是否有子目录使用file.isDirectory()
         判断文件是否存在使用file.exists()
继承、重载、覆盖问题?
  答:继承:子类继承父类,子类可以拥有父类中已定义的方法,并且子类可以修改父类中的方法使其更适合特殊需求。
         重载:在一个类中方法名和返回类型相同,参数不同。
         覆盖:在子类中覆盖父类的某个方法,要求方法名相同,参数类型相同。
Statement和PreparedStatement之间的区别?
  答:Statement比PreparedStatement速度慢
         PreparedStatement是预编译,插入时速度高于Statement
         Statement创建速度很慢,常用选择PreparedStatement
Session机制?
  答:session机制是一种服务器端机制,服务器使用一种类似于散列表的结构来保存信息。
jsp和servlet中的请求转发分别如何实现?
  答:jsp可以使用jsp:forward标签转发
         servlet可以使用request.getRequestDispatcher()实现转发
介绍j2ee、j2se、j2me的区别?
  答:j2ee(企业版):主要用于企业web开发
         j2se(标准版):主要用于web开发,但缺少企业版的一些特性
         j2me(微小版):主要用于手机开发
J2ee提供的技术?
  答:j2ee提供的技术有EJB、servlet、jsp等。
什么是Application Server?
  答:Application Server 应用服务器
简单介绍连接池的优点和原理?
  答:数据库连接和关闭是比较花费时间的一件事,而连接池可以提高我们的工作效率。
         刚开始创建一定数量的池连接,当需要时从池连接中拿出一个,用完之后再把这个连接重新放回连接池。
Web.xml的作用?
  答:Web.xml会在程序启动时执行,如果想在程序刚启动的时候执行一些方法的话可以配置在Web.xml中。
简单介绍您所了解的MVC?
  答:在项目中使用MVC模式会使项目分工更加明确,结构更加清晰
         M model 模型层:JavaBean
         V view 视图层:jsp html
         C controller 控制层:servlet
简单介绍你所了解的XML?
  答:XML可扩展标记语言,可以用来标记数据,定义数据结构,是一种允许用户自定义标记的语言
简单介绍您所了解的structs、spring和hibernate?
  答:struts:控制层Action,页面标签和Model数据,调用业务层
         Spring:Aop管理事务控制,IOC管理各个组件的耦合
         Hibernate:负责数据库和对象的映射,负责Dao层
因为你去公司面试,公司让你写笔试,不可能说XX一个题目写两页纸写的太详细,所以以上答案有的可能比较简短,没有说出重点,请大家补充,如果大家有什么更好的答案请拿出来一起分享
                                    前言:本资源来自于javaeye,原资源链接地址:http://www.javaeye.com/topic/67398
原文如下:
以前写了一个java的正规表达式的java工具类,分享一下,有用到的欢迎下载使用。
如果你有常用的定义好的,且测试通过的正规表达式,欢迎跟贴,也让我享用一下 .
类中用到了 jakarta-oro-2.0.jar 包,请大家自己在 apache网站下下载
在这是junit测试单元类我就不提交了,在main()方法中有几个小测试,有兴趣自己玩吧.
这个工具类目前主要有25种正规表达式(有些不常用,但那时才仔细深入的研究了一下正规,写上瘾了,就当时能想到的都写了):
 1.匹配图象;                      2 匹配email地址;                    3 匹配匹配并提取url ;                         4 匹配并提取http ;
 5.匹配日期                       6 匹配电话;                               7 匹配身份证                                       8 匹配邮编代码
9. 不包括特殊字符的匹配 (字符串中不包括符号 数学次方号^ 单引号' 双引号" 分号; 逗号, 帽号: 数学减号- 右尖括号> 左尖括号 0)
12 匹配正整数                                                                      13  匹配非正整数(负整数 + 0)                                                
14 匹配负整数;                                                                      15. 匹配整数 ;
16 匹配非负浮点数(正浮点数 + 0)                                17. 匹配正浮点数
18 匹配非正浮点数(负浮点数 + 0)                                19 匹配负浮点数;                          
 20 .匹配浮点数;                                                                      21. 匹配由26个英文字母组成的字符串;   
22. 匹配由26个英文字母的大写组成的字符串                   23 匹配由26个英文字母的小写组成的字符串 
24 匹配由数字和26个英文字母组成的字符串;                   25  匹配由数字、26个英文字母或者下划线组成的字符串;
java源码:
 * Created on 2005-4-15
 * Summary of regular-expression constructs										正则表达式结构简介:
 * Construct Matches
 *	Characters																	字符:
 *		x The character x															x   字符 x
 *		\\ The backslash character													\\  反斜杠
 *		\0n The character with octal value 0n (0 <= n <= 7)							\0n     十进制数 (0 <= n <= 7)
 *		\0nn The character with octal value 0nn (0 <= n <= 7)						\0nn    十进制数 0nn (0 <= n <= 7)
 *		\0mnn The character with octal value 0mnn (0 <= m <= 3, 0 <= n <= 7)		\0mnn   十进制数 0mnn (0 <= m <= 3, 0 <= n <= 7)
 *		\xhh The character with hexadecimal value 0xhh								\xhh    十六进制数 0x
                                    当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
Subject:抽象被观察者,把所有观察者对象引用保存到集合中,然后 
提供添加,移除,和通知观察者对象更新的方法。
ConcreteSubject:被观察者,集合存放观察者,重写增删和通知观察者 
的方法,当发生变化时通知观察者更新。
Observer:抽象观察者,定义一个更新接口,给被观察者更新的时候调
ConcreteObserver:具体观察者,继承抽象观察者,实现具体的更新方法
  假设有三个人,拍卖师,拍卖者1,
我现在在英国一家软件公司任技术带头人。我是计算机科学的硕士。我主要使用 .NET 1.1/2.0, C#, VB.NET, ASP.NET, VC++ 6, MFC, ATL, COM/DCOM, SQL Server 2000/2005等。最近我在学习 .NET 3.x 的全部内容。我的免费源代码和文章网站是 http://aishai.netfirms.com
职业:团队带头人
位置:英国
C# 是一种具有 C++ 特性,Java 样式及 BASIC 快速建模特性的编程语言。如果你已经知晓 C++ 语言,本文将在不到一小时的时间内带你快速浏览 C# 的语法。如果熟悉 Java 语言,Java 的编程结构、打包和垃圾回收的概念肯定对你快速学习 C# 大有帮助。所以我在讨论 C# 语言构造的时候会假设你知道 C++。
本文通过一系列例程以简短但全面的方式讨论了 C# 语言构造和特性,所以你仅需略览代码片刻,即可了解其概念。
注意:本文不是为 C# 宗师而写。有很多初学者的 C# 文章,这只是其中之一。
接下来关于 C# 的讨论主题:
?    编程结构
?    命名空间
?    数据类型
?    变量
?    运算符与表达式
?    枚举
?    语句
?    类与结构
?    修饰符
?    属性
?    接口
?    函数参数
?    数组
?    索引器
?    装箱与拆箱
?    委托
?    继承与多态
以下主题不会进行讨论:
?    C++ 与 C# 的共同点
?    诸如垃圾回收、线程、文件处理等概念
?    数据类型转换
?    异常处理
?    .NET 库
和 C++ 一样,C# 是大小写敏感的。半角分号(;)是语句分隔符。和 C++ 有所区别的是,C# 中没有单独的声明(头)和实现(CPP)文件。所有代码(类声明和实现)都放在扩展名为 cs 的单一文件中。
看看 C# 中的 Hello World 程序。
复制内容到剪贴板
using System;
namespace MyNameSpace
class HelloWorld
    static void Main(string[] args)
        Console.WriteLine ("Hello World");
C# 中所有内容都打包在类中,而所有的类又打包在命名空间中(正如文件存与文件夹中)。和 C++ 一样,有一个主函数作为你程序的入口点。C++ 的主函数名为 main,而 C# 中是大写 M 打头的 Main。
类块或结构定义之后没有必要再加一个半角分号。C++ 中是这样,但 C# 不要求。
每个类都打包于一个命名空间。命名空间的概念和 C++ 完全一样,但我们在 C# 中比在 C++ 中更加频繁的使用命名空间。你可以用点(.)定界符访问命名空间中的类。上面的 Hello World 程序中,MyNameSpace 是其命名空间。
现在思考当你要从其他命名空间的类中访问 HelloWorld 类。
复制内容到剪贴板
using System;
namespace AnotherNameSpace
    class AnotherClass
        public void Func()
            Console.WriteLine ("Hello World");
现在在你的 HelloWorld 类中你可以这样访问:
复制内容到剪贴板
using System;
using AnotherNameSpace; // 你可以增加这条语句
namespace MyNameSpace
class HelloWorld
    static void Main(string[] args) 
        AnotherClass obj = new AnotherClass(); 
        obj.Func();
在 .NET 库中,System 是包含其他命名空间的顶层命名空间。默认情况下存在一个全局命名空间,所以在命名空间外定义的类直接进到此全局命名空间中,因而你可以不用定界符访问此类。
你同样可以定义嵌套命名空间。
Using
#include 指示符被后跟命名空间名的 using 关键字代替了。正如上面的 using System。System 是最基层的命名空间,所有其他命名空间和类都包含于其中。System 命名空间中所有对象的基类是 Object。
除了以下差异,C# 中的变量几乎和 C++ 中一样:
1.    C# 中(不同于 C++)的变量,总是需要你在访问它们前先进行初始化,否则你将遇到编译时错误。故而,不可能访问未初始化的变量。
2.    你不能在 C# 中访问一个“挂起”指针。
3.    超出数组边界的表达式索引值同样不可访问。
4.    C# 中没有全局变量或全局函数,取而代之的是通过静态函数和静态变量完成的。
所有 C# 的类型都是从 object 类继承的。有两种数据类型:
1.    基本/内建类型
2.    用户定义类型
以下是 C# 内建类型的列表:
类型        字节        描述
byte        1          unsigned byte 
sbyte      1          signed byte 
short      2          signed short 
ushort      2          unsigned short 
int        4          signed integer 
uint        4          unsigned integer 
long        8          signed long 
ulong      8          unsigned long 
float      4          floating point number 
double      8          double precision number 
decimal    8          fixed precision number 
string      -          Unicode string 
char        -          Unicode char 
bool        true, false boolean 
注意:C# 的类型范围和 C++ 不同。例如:long 在 C++ 中是 4 字节而在 C# 中是 8 字节。bool 和 string 类型均和 C++ 不同。bool 仅接受真、假而非任意整数。
用户定义类型文件包含:
1.    类 (class)
2.    结构(struct)
3.    接口(interface)
以下类型继承时均分配内存:
1.    值类型
2.    参考类型
值类型是在堆栈中分配的数据类型。它们包括了:
?    除字符串,所有基本和内建类型
?    结构
?    枚举类型
引用类型
引用类型在堆(heap)中分配内存且当其不再使用时,将自动进行垃圾清理。和 C++ 要求用户显示创建 delete 运算符不一样,它们使用新运算符创建,且没有 delete 运算符。在 C# 中它们自动由垃圾回收系统回收。
引用类型包括:
?    类
?    接口
?    集合类型如数组
?    字符串
C# 中的枚举和 C++ 完全一样。通过关键字 enum 定义。
复制内容到剪贴板
enum Weekdays
    Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday
除了内存分配的不同外,类和结构就和 C++ 中的情况一样。类的对象在堆中分配,并使用 new 关键字创建。而结构是在栈(stack)中进行分配。C# 中的结构属于轻量级快速数据类型。当需要大型数据类型时,你应该创建类。
复制内容到剪贴板
struct Date
    int day;
    int month;
    int year;
class Date
    int day;
    int month;
    int year;
    string weekday; 
    string monthName;
    public int GetDay()
        return day;
    public int GetMonth() 
        return month;
    public int GetYear() 
        return year;
    public void SetDay(int Day) 
        day = Day ;
    public void SetMonth(int Month)
        month = Month;
    public void SetYear(int Year)
        year = Year;
    public bool IsLeapYear()
        return (year/4 == 0);
    public void SetDate (int day, int month, int year)
如果你熟悉 C++ 面向对象的方法,你一定对属性有自己的认识。对 C++ 来说,前面例子中 Date 类的属性就是 day、month 和 year,而你添加了 Get 和 Set 方法。C# 提供了一种更加便捷、简单而又直接的属性访问方式。
所以上面的类应该写成这样:
复制内容到剪贴板
using System;
class Date
    public int Day{
        get {
            return day; 
        set {
            day = value; 
    int day;
    public int Month{
        get { 
            return month;
        set {
            month = value; 
    int month;
    public int Year{
        get { 
            return year;
        set {
            year = value;
    int year;
    public bool IsLeapYear(int year)
        return year%4== 0 ? true: false; 
    public void SetDate (int day, int month, int year)
        this.day = day;
        this.month = month;
        this.year = year;
这里是你 get 和 set 属性的方法:
复制内容到剪贴板
class User
  public static void Main()
        Date date = new Date(); 
        date.Day = 27; 
        date.Month = 6; 
        date.Year = 2003;
        Console.WriteLine
        ("Date: {0}/{1}/{2}", date.Day, date.Month, date.Year);
你必须知道 C++ 中常用的 public、private 和 protected 修饰符。我将在这里讨论一些 C# 引入的新的修饰符。
readonly
readonly 修饰符仅用于修饰类的数据成员。正如其名字说的,一旦它们已经进行了写操作、直接初始化或在构造函数中对其进行了赋值,readonly 数据成员就只能对其进行读取。readonly 和 const 数据成员不同之处在于 const 要求你在声明时进行直接初始化。看下面的例程:
复制内容到剪贴板
class MyClass
    const int constInt = 100; //直接进行
    readonly int myInt = 5; //直接进行
    readonly int myInt2;
    public MyClass()
        myInt2 = 8;        //间接进行
    public Func()
        myInt = 7; //非法
        Console.WriteLine(myInt2.ToString());
sealed
带有 sealed 修饰符的类不允许你从它继承任何类。所以如果你不想一个类被继承,你可以对该类使用 sealed 关键字。
复制内容到剪贴板
sealed class CanNotbeTheParent
    int a = 5;
unsafe
你可以使用 unsafe 修饰符在 C# 中定义一个不安全上下文。在不安全上下文中,你可以插入不安全代码,如 C++ 的指针等。参见以下代码:
复制内容到剪贴板
public unsafe MyFunction( int * pInt, double* pDouble)
    int* pAnotherInt = new int;
    *pAnotherInt  = 10;
    pInt = pAnotherInt;
    *pDouble = 8.9;    
如果你有 COM 的思想,你马上就知道我在说什么了。接口是只包含函数签名而在子类中实现的抽象基类。在 C# 中,你可以用 interface 关键字声明这样的接口类。.NET 就是基于这样的接口的。C# 中你不能对类进行多重继承——这在 C++ 中是允许的。通过接口,多重继承的精髓得以实现。即你的子类可以实现多重接口。(译注:由此可以实现多重继承)
复制内容到剪贴板
using System;
interface myDrawing
    int originx
    int originy
    void Draw(object shape);            
class Shape: myDrawing
    int OriX;
    int OriY;
    public int originx
            return OriX;
            OriX = value;
    public int originy
            return OriY;
            OriY = value;
    public void Draw(object shape)
        ... // 做要做的事 
    // 类自身的方法
    public void MoveShape(int newX, int newY)
    .....
数组在 C# 中比 C++ 中要高级很多。数组分配于堆中,所以是引用类型的。你不能访问数组边界外的元素。所以 C# 防止你引发那种 bug。同时也提供了迭代数组元素的帮助函数。foreach 是这样的迭代语句之一。C++ 和 C# 数组的语法差异在于:
方括号在类型后面而不是在变量名后面
创建元素使用 new 运算符
C# 支持一维、多维和交错数组(数组的数组)
复制内容到剪贴板
int[] array = new int[10]; // int 型一维数组
for (int i = 0; i < array.Length; i++) 
    array = i; 
int[,] array2 = new int[5,10]; // int 型二维数组
array2[1,2] = 5;
int[,,] array3 = new int[5,10,5]; // int 型三维数组
array3[0,2,4] = 9;
int[][] arrayOfarray = new int[2]; // int 型交错数组 - 数组的数组
arrayOfarray[0] = new int[4]; 
arrayOfarray[0] = new int[] {1,2,15};
索引器用于书写一个可以通过使用 [] 像数组一样直接访问集合元素的方法。你所需要的只是指定待访问实例或元素的索引。索引器的语法和类属性语法相同,除了接受作为元素索引的输入参数外。
注意:CollectionBase 是用于建立集合的库类。List 是 CollectionBase 中用于存放集合列表的受保护成员。
复制内容到剪贴板
class Shapes: CollectionBase 
    public void add(Shape shp)
        List.Add(shp);
    //indexer
    public Shape this[int index]
        get { 
            return (Shape) List[index];
        set {
            List[index] = value ;
装箱/拆箱
装箱的思想在 C# 中是创新的。正如前面提到的,所有的数据类型,无论是内建的还是用户定义的,都是从 System 命名空间的基类 object 继承的。所以基础的或是原始的类型打包为一个对象称为装箱,相反的处理称为拆箱。
复制内容到剪贴板
class Test
  static void Main() 
      int myInt = 12;
      object obj = myInt ;      // 装箱
      int myInt2 = (int) obj;  // 拆箱
例程展示了装箱和拆箱两个过程。一个 int 值可以被转换为对象,并且能够再次转换回 int。当某种值类型的变量需要被转换为一个引用类型时,便会产生一个对象箱保存该值。拆箱则完全相反。当某个对象箱被转换回其原值类型时,该值从箱中拷贝至适当的存储空间。
C# 中的参数有三种类型:
1.    按值传递/输入参数
2.    按引用传递/输入-输出参数
3.    输出参数
如果你有 COM 接口的思想,而且还是参数类型的,你会很容易理解 C# 的参数类型。
按值传递/输入参数
值参数的概念和 C++ 中一样。传递的值复制到了新的地方并传递给函数。
复制内容到剪贴板
SetDay(5);
void SetDay(int day) 
按引用传递/输入-输出参数
C++ 中的引用参数是通过指针或引用运算符 & 传递的。C# 中的引用参数更不易出错。你可以传递一个引用地址,你传递一个输入的值并通过函数得到一个输出的值。因此引用参数也被称为输入-输出参数。
你不能将未初始化的引用参数传递给函数。C# 使用关键字 ref 指定引用参数。你同时还必须在传递参数给要求引用参数的函数时使用关键字 ref。
复制内容到剪贴板
int a= 5;
FunctionA(ref a); // 使用 ref,否则将引发编译时错误
Console.WriteLine(a); // 打印 20
复制内容到剪贴板
void FunctionA(ref int Val)
    int x= Val; 
    Val = x* 4;    
输出参数是只从函数返回值的参数。输入值不要求。C# 使用关键字 out 表示输出参数。
复制内容到剪贴板
int Val;
    GetNodeValue(Val);
复制内容到剪贴板
bool GetNodeValue(out int Val)
        Val = value;
        return true; 
参数和数组的数量变化
C# 中的数组使用关键字 params 进行传递。一个数组类型的参数必须总是函数最右边的参数。只有一个参数可以是数组类型。你可以传送任意数量的元素作为数组类型的参数。看了下面的例子你可以更好的理解:
注意:使用数组是 C# 提供用于可选或可变数量参数的唯一途径。
复制内容到剪贴板
void Func(params int[] array)
        Console.WriteLine("number of elements {0}", array.Length);
复制内容到剪贴板
Func(); // 打印 0
    Func(5); // 打印 1
    Func(7,9); // 打印 2
    Func(new int[] {3,8,10}); // 打印 3
    int[] array = new int[8] {1,3,4,5,5,6,7,5};
    Func(array); // 打印 8
运算符与表达式
运算符和表达式跟 C++ 中完全一致。然而同时也添加了一些新的有用的运算符。有些在这里进行了讨论。
is 运算符
is 运算符是用于检查操作数类型是否相等或可以转换。is 运算符特别适合用于多态的情形。is 运算符使用两个操作数,其结果是布尔值。参考例子:
复制内容到剪贴板
void function(object param)
    if(param is ClassA)
        //做要做的事
    else if(param is MyStruct)
        //做要做的事        
as 运算符
as 运算符检查操作数的类型是否可转换或是相等(as 是由 is 运算符完成的),如果是,则处理结果是已转换或已装箱的对象(如果操作数可以装箱为目标类型,参考 装箱/拆箱)。如果对象不是可转换的或可装箱的,返回值为 null。看看下面的例子以更好的理解这个概念。
复制内容到剪贴板
Shape shp = new Shape(); 
Vehicle veh = shp as Vehicle; // 返回 null,类型不可转换
Circle cir = new Circle(); 
Shape shp = cir; 
Circle cir2 = shp as Circle;  //将进行转换
object[] objects = new object[2];
objects[0] = "Aisha";
object[1] = new Shape();
string str;
for(int i=0; i&< objects.Length; i++)
    str = objects as string;
    if(str == null)
        Console.WriteLine("can not be converted");
        Console.WriteLine("{0}",str);
复制内容到剪贴板
Output:
Aisha
can not be converted
除了些许附加的新语句和修改外,C# 的语句和 C++ 的基本一致。
以下是新的语句:
foreach
用于迭代数组等集合。
复制内容到剪贴板
foreach (string s in array) 
        Console.WriteLine(s);
在线程中使代码块称为重点部分。
(译注:lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。)
checked/unchecked
用于数字操作中的溢出检查。
复制内容到剪贴板
int x = Int32.MaxValue; x++; // 溢出检查 
x++; // 异常
unchecked
x++; // 溢出
下面的语句已修改:(译注:原文如此,疑为作者笔误)
Switch
Switch 语句在 C# 中修改过。
1.现在在执行一条 case 语句后,程序流不能跳至下一 case 语句。之前在 C++ 中这是可以的。
复制内容到剪贴板
int var = 100;
switch (var) 
    case 100: Console.WriteLine(""); // 这里没有 break 
    case 200: Console.WriteLine(""); break; 
C++ 的输出:
复制内容到剪贴板
而在 C# 中你将得到一个编译时错误:
复制内容到剪贴板
error CS0163: Control cannot fall through 
      from one case label ('case 100:') to another
2.然而你可以像在 C++ 中一样这么用:
复制内容到剪贴板
switch (var) 
    case 100: 
    case 200: Console.WriteLine("100 or 200"); break; 
3.你还可以用常数变量作为 case 值:
复制内容到剪贴板
const string WeekEnd = "Sunday";
const string WeekDay1 = "Monday";
string WeekDay = Console.ReadLine();
switch (WeekDay ) 
case WeekEnd: Console.WriteLine("It's weekend!!"); break; 
case WeekDay1: Console.WriteLine("It's Monday"); break;
委托让我们可以把函数引用保存在变量中。这就像在 C++ 中使用 typedef 保存函数指针一样。
委托使用关键字 delegate 声明。看看这个例子,你就能理解什么是委托:
复制内容到剪贴板
delegate int Operation(int val1, int val2);
public int Add(int val1, int val2) 
    return val1 + val2; 
public int Subtract (int val1, int val2) 
    return val1- val2;
public void Perform()
    Operation Oper;
    Console.WriteLine("Enter + or - ");
    string optor = Console.ReadLine();
    Console.WriteLine("Enter 2 operands");
    string opnd1 = Console.ReadLine();
    string opnd2 = Console.ReadLine();
    int val1 = Convert.ToInt32 (opnd1);            
    int val2 = Convert.ToInt32 (opnd2);
    if (optor == "+")
        Oper = new Operation(Add);
        Oper = new Operation(Subtract);
    Console.WriteLine(" Result = {0}", Oper(val1, val2));
继承与多态
C# 只允许单一继承。多重继承可以通过接口达到。
复制内容到剪贴板
class Parent{
class Child : Parent
虚函数在 C# 中同样是用于实现多态的概念的,除了你要使用 override 关键字在子类中实现虚函数外。父类使用同样的 virtual 关键字。每个重写虚函数的类都使用 override 关键字。(译注:作者所说的“同样”,“除……外”都是针对 C# 和 C++ 而言的)
复制内容到剪贴板
class Shape
    public virtual void Draw()
        Console.WriteLine("Shape.Draw")    ;
class Rectangle : Shape
    public override void Draw()
        Console.WriteLine("Rectangle.Draw");
class Square : Rectangle
    public override void Draw()
        Console.WriteLine("Square.Draw");
class MainClass
    static void Main(string[] args)
        Shape[] shp = new Shape[3];
        Rectangle rect = new Rectangle();
        shp[0] = new Shape();
        shp[1] = rect;
        shp[2] = new Square();
        shp[0].Draw();
        shp[1].Draw();
        shp[2].Draw();
Output:
Shape.Draw
Rectangle.Draw
Square.Draw
使用“new”隐藏父类函数
你可以隐藏基类中的函数而在子类中定义其新版本。关键字 new 用于声明新的版本。思考下面的例子,该例是上一例子的修改版本。注意输出,我用 关键字 new 替换了 Rectangle 类中的关键字 override。
复制内容到剪贴板
class Shape
    public virtual void Draw()
        Console.WriteLine("Shape.Draw")    ;
class Rectangle : Shape
    public new void Draw()
        Console.WriteLine("Rectangle.Draw");
class Square : Rectangle
    //这里不用 override
    public new void Draw() 
        Console.WriteLine("Square.Draw");
class MainClass
    static void Main(string[] args)
        Console.WriteLine("Using Polymorphism:");
        Shape[] shp = new Shape[3];
        Rectangle rect = new Rectangle();
        shp[0] = new Shape();
        shp[1] = rect;
        shp[2] = new Square();
        shp[0].Draw();
        shp[1].Draw();
        shp[2].Draw();
        Console.WriteLine("Using without Polymorphism:");
        rect.Draw();            
        Square sqr = new Square();
        sqr.Draw();
Output:
Using Polymorphism
Shape.Draw
Shape.Draw
Shape.Draw
Using without Polymorphism:
Rectangle.Draw
Square.Draw
多态性认为 Rectangle 类的 Draw 方法是和 Shape 类的 Draw 方法不同的另一个方法,而不是认为是其多态实现。所以为了防止父类和子类间的命名冲突,我们只有使用 new 修饰符。
注意:你不能在一个类中使用一个方法的两个版本,一个用 new 修饰符,另一个用 override 或 virtual。就像在上面的例子中,我不能在 Rectangle 类中增加另一个名为 Draw 的方法,因为它是一个 virtual 或 override 的方法。同样在 Square 类中,我也不能重写 Shape 类的虚方法 Draw。
调用基类成员
如果子类的数据成员和基类中的有同样的名字,为了避免命名冲突,基类成员和函数使用 base 关键字进行访问。看看下面的例子,基类构造函数是如何调用的,而数据成员又是如何使用的。
复制内容到剪贴板
public Child(int val) :base(val)
    myVar = 5;
    base.myVar;
public Child(int val)
    base(val);
    myVar = 5 ;
    base.myVar;
本文仅仅是作为 C# 语言的一个快速浏览,以便你可以熟悉该语言的一些特性。尽管我尝试用实例以一种简短而全面的方式讨论了 C# 几乎所有的主要概念,但我认为还是有很多内容需要增加和讨论的。
以后,我会增加更多的没有讨论过的命令和概念,包括事件等。我还想给初学者写一下怎么用 C# 进行 Windows 编程。
参考文献:
我们都知道的 MSDN
Tom Archer 著,Inside C#
Eric Gunnerson 著,A Programmer's Introduction to C#
Karli Watson 著,Beginning C#
O'Reilly(奥莱利出版),Programming C# 
2003年6月12日:按引用传递/输入-输出参数一节中增加了 ref 关键字
2003年6月20日:为可选参数增加了一条注意事项,纠正了交错数组例子中赋值运算符的笔误
本文及其任何关联的源代码和文件均以 The Code Project Open License (CPOL)执行。(译注:代码计划网站公开许可)
                                    前言    今天逛了下论坛,发现有一种说法,集合不能存储基本类型,都是存储对象,我自己实验了下,List&lt;int&gt;报错了,而List&lt;Integer&gt;则通过了编译。行吧,暂且认同这种说法。    本篇主要是说明集合中存入对象的问题。对象存入集合都是以内存地址的形式存入,当存入之后,修改了对象的值,就算没有直接操作对象,那么对象里的值也会改变。案例1List中存入Map集合对...
                                    java的容器中可以放基本的数据类型,但是是以包装类的形式,如int 在 容器中是先包装成Integer,再转变成Object存放集合中也可以放类的实例化对象。
    任何一种数据类型或者对象放进容器中后都会失去原有的类型,变成 Object,用的时候从容器中取出后进行转型成所需的类型就可以了,《Think in java》 中是这样解释的: 由于当初编写集合时,那个集合的程序员根本不知道用
                                    集合引用类型:Object、Array(创建数组,数组空位,数组索引,检测数组,迭代器方法,复制和填充方法,转换方法,栈方法,队列方法,排序方法,操作方法,搜索和位置方法,迭代方法,归并方法)、定型数组(ArrayBuffer,DataView)、Map(基本API,Object 与 Map 对比,get(),set(),delete(),clear())、WeakMap、Set、WeakSet使用弱映射
下面分别看一下修改对象属性值和修改对象引用后的效果。
案例一,修改对象属性值
创建几个对象添加到List中,然后修改对象的属性值,那么List中的元素的属性值会随之改变,比如下面的例子:
public static void test1() {
    List<Order> list = new ArrayList<>();
    for (int i = 0; i < 3; i++) {
        Order o
                                    前言集合作为一种存储数据的容器,是我们日常开发中使用最频繁的对象类型之一。 在面试中我们经常被问到 ArrayList 和 LinkedList 的区别。相信大部分同学都能回上:“ArrayList 是基于数组实现,LinkedList 是基于链表实现。相应地,也就是说在新增、删除元素时,LinkedList 的效率要高于 ArrayList,而在遍历的时候,ArrayList 的效率要高于 Li...
                                    1.请说出ArrayList、Vector、LinkedList的存储性能和特性。
ArrayList底层 数组结构,线程不安全 线程异步 效率高 查找快 增加删除慢
Vector、底层数组结构  线程同步 线程安全 效率低 存储的是键值对
LinkedList :底层双向链表结构  查找慢 增加删除快  线程异步,不安全,效率高
2.数组有没有length()这个方法?String有没有leng...
                                    //导入的包。import java.util.ArrayList;//用集合存储对象,遍历集合,取所有元素。  用get方法。//创建的一个类。public class zylx4 {//公共静态的主方法。    public static void main(String[] args){  //创建集合。        ArrayList<Integer> array ...