java百战1573答案4.doc_第1页
java百战1573答案4.doc_第2页
java百战1573答案4.doc_第3页
java百战1573答案4.doc_第4页
java百战1573答案4.doc_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

4、final参数当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。publicclassTest4publicstaticvoidmain(Stringargs)newTest4().f1(2);publicvoidf1(finalinti)/i+;/i是final类型的,值不允许改变的.System.out.print(i);二、staticstatic表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象市,不生成static变量的副本,而是类的所有实例共享同一个static变量。static变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用(当然也可以在非静态成员方法中使用-废话),但是不能在其他类中通过类名来直接引用,这一点很重要。实际上你需要搞明白,private是访问权限限定,static表示不要实例化就可以使用,这样就容易理解多了。static前面加上其它访问权限关键字的效果也以此类推。static修饰的成员变量和成员方法习惯上称为静态变量和静态方法,可以直接通过类名来访问,访问语法为:类名.静态方法名(参数列表.)类名.静态变量名用static修饰的代码块表示静态代码块,当Java虚拟机(JVM)加载类时,就会执行该代码块(用处非常大,呵呵)。1、static变量按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量;另一种是没有被static修饰的变量,叫实例变量。两者的区别是:对于静态变量在内存中只有一个拷贝(节省内存),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)。对于实例变量,没创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响(灵活)。2、静态方法静态方法可以直接通过类名调用,任何的实例也都可以调用,因此静态方法中不能用this和super关键字,不能直接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员成员方法),只能访问所属类的静态成员变量和成员方法。因为实例成员与特定的对象关联!这个需要去理解,想明白其中的道理,不是记忆!因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract。3、static代码块static代码块也叫静态代码块,是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。例如:publicclassTest5privatestaticinta;privateintb;staticTest5.a=3;System.out.println(a);Test5t=newTest5();t.f();t.b=1000;System.out.println(t.b);staticTest5.a=4;System.out.println(a);publicstaticvoidmain(Stringargs)/TODO自动生成方法存根staticTest5.a=5;System.out.println(a);publicvoidf()System.out.println(hhahhahah);运行结果:3hhahhahah100045利用静态代码块可以对一些static变量进行赋值,最后再看一眼这些例子,都一个static的main方法,这样JVM在运行main方法的时候可以直接调用而不用创建实例。4、static和final一块用表示什么staticfinal用来修饰成员变量和成员方法,可简单理解为“全局常量”!对于变量,表示一旦给值就不可修改,并且通过类名可以访问。对于方法,表示不可覆盖,并且可以通过类名直接访问。final修饰的方法能不能被重载?能不能被重写?Final修饰的方法能被重载,不能被重写String类能不能被继承?为什么?被final修饰的类不能被继承,String类被final修饰了包含抽象方法的类是抽象类吗? 抽象类一定包含抽象方法吗?对,包含抽象方法的类一定是抽象类,抽象类一定包含抽象方法,都正确抽象类中能不能有普通方法?能不能定义构造方法?抽象类中由普通方法,可以有构造方法但是不能创建对象抽象类能不能被new出来?即抽象类的构造方法能不能被调用?抽象类不能被new出来,抽象类的构造方法在子类实例化的时候被调用接口中只能定义常量和抽象方法吗?对,不能有方法体接口描述了现实世界中什么逻辑?模型接口中的常量一定是public static final吗?抽象方法一定是public abstract吗?对接口中能不能定义普通变量,普通方法?从设计接口的角度说明为什么这么做?不能,接口本身就是抽象的,不能有实例化接口能不能被new?接口不能被new接口中有没有多继承?有,一个接口可以继承多个接口一个类能不能实现多个接口?一个类可以实现多个接口【上机】完成抽象类、接口的语法测试代码【上机】使用接口,定义电子产品系统(智能手机、MP3、智能手表)。如何对一个数组的多个对象按照不同的依据进行排序;模拟实现Comparable和Comparator接口;GC指的是什么?写出英文全称。垃圾回收机制中,程序员能不能调用垃圾回收器?GC,Garbage Collect,中文意思就是垃圾回收,指的是系统中的内存的分配和回收管理。其对系统性能的影响是不可小觑的。今天就来说一下关于GC优化的东西,这里并不着重说概念和理论,主要说一些实用的东西。关于概念和理论这里只做简单说明,具体的大家可以看微软官方文档。一、什么是GC GC如其名,就是垃圾收集,当然这里仅就内存而言。Garbage Collector(垃圾收集器,在不至于混淆的情况下也成为GC)以应用程序的root为基础,遍历应用程序在Heap上动态分配的所有对象2,通过识别它们是否被引用来确定哪些对象是已经死亡的、哪些仍需要被使用。已经不再被应用程序的root或者别的对象所引用的对象就是已经死亡的对象,即所谓的垃圾,需要被回收。这就是GC工作的原理。为了实现这个原理,GC有多种算法。比较常见的算法有Reference Counting,Mark Sweep,Copy Collection等等。目前主流的虚拟系统.NET CLR,Java VM和Rotor都是采用的Mark Sweep算法。(此段内容来自网络).NET的GC机制有这样两个问题:首先,GC并不是能释放所有的资源。它不能自动释放非托管资源。第二,GC并不是实时性的,这将会造成系统性能上的瓶颈和不确定性。GC并不是实时性的,这会造成系统性能上的瓶颈和不确定性。所以有了IDisposable接口,IDisposable接口定义了Dispose方法,这个方法用来供程序员显式调用以释放非托管资源。使用using语句可以简化资源管理。二、托管资源和非托管资源 托管资源指的是.NET可以自动进行回收的资源,主要是指托管堆上分配的内存资源。托管资源的回收工作是不需要人工干预的,有.NET运行库在合适调用垃圾回收器进行回收。非托管资源指的是.NET不知道如何回收的资源,最常见的一类非托管资源是包装操作系统资源的对象,例如文件,窗口,网络连接,数据库连接,画刷,图标等。这类资源,垃圾回收器在清理的时候会调用Object.Finalize()方法。默认情况下,方法是空的,对于非托管对象,需要在此方法中编写回收非托管资源的代码,以便垃圾回收器正确回收资源。在.NET中,Object.Finalize()方法是无法重载的,编译器是根据类的析构函数来自动生成Object.Finalize()方法的,所以对于包含非托管资源的类,可以将释放非托管资源的代码放在析构函数。三、关于GC优化的一个例子 正常情况下,我们是不需要去管GC这些东西的,然而GC并不是实时性的,所以我们的资源使用完后,GC什么时候回收也是不确定的,所以会带来一些诸如内存泄漏、内存不足的情况,比如我们处理一个约500M的大文件,用完后GC不会立刻执行清理来释放内存,因为GC不知道我们是否还会使用,所以它就等待,先去处理其他的东西,过一段时间后,发现这些东西不再用了,才执行清理,释放内存。下面,来介绍一下GC中用到的几个函数:GC.SuppressFinalize(this); /请求公共语言运行时不要调用指定对象的终结器。GC.GetTotalMemory(false); /检索当前认为要分配的字节数。一个参数,指示此方法是否可以等待较短间隔再返回,以便系统回收垃圾和终结对象。GC.Collect(); /强制对所有代进行即时垃圾回收。GC运行机制写代码前,我们先来说一下GC的运行机制。大家都知道GC是一个后台线程,他会周期性的查找对象,然后调用Finalize()方法去消耗他,我们继承IDispose接口,调用Dispose方法,销毁了对象,而GC并不知道。GC依然会调用Finalize()方法,而在.NET 中Object.Finalize()方法是无法重载的,所以我们可以使用析构函数来阻止重复的释放。我们调用完Dispose方法后,还有调用GC.SuppressFinalize(this) 方法来告诉GC,不需要在调用这些对象的Finalize()方法了。下面,我们新建一个控制台程序,加一个Factory类,让他继承自IDispose接口,代码如下:using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace GarbageCollect public class Factory : IDisposable private StringBuilder sb = new StringBuilder(); List list = new List(); /拼接字符串,创造一些内存垃圾 public void MakeSomeGarbage() for (int i = 0; i 50000; i+) sb.Append(i.ToString(); /销毁类时,会调用析构函数 Factory() Dispose(false); public void Dispose() Dispose(true); protected virtual void Dispose(bool disposing) if (!disposing) return; sb = null; GC.Collect(); GC.SuppressFinalize(this); 只有继承自IDispose接口,使用这个类时才能使用Using语句,在main方法中写如下代码:using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Diagnostics;namespace GarbageCollect class Program static void Main(string args) using(Factory f = new Factory() f.MakeSomeGarbage(); Console.WriteLine(Total memory is 0 KBs., GC.GetTotalMemory(false) / 1024); Console.WriteLine(After GC total memory is 0 KBs., GC.GetTotalMemory(false) / 1024); Console.Read(); 运行结果如下,可以看到资源运行MakeSomeGarbage()函数后的内存占用为1796KB,释放后成了83Kb.代码运行机制:我们写了Dispose方法,还写了析构函数,那么他们分别什么时候被调用呢?我们分别在两个方法上面下断点。调试运行,你会发现先走到了Dispose方法上面,知道程序运行完也没走析构函数,那是因为我们调用了GC.SuppressFinalize(this)方法,如果去掉这个方法后,你会发现先走Dispose方法,后面又走析构函数。所以,我们可以得知,如果我们调用Dispose方法,GC就会调用析构函数去销毁对象,从而释放资源。四、什么时候该调用GC.Collect 这里为了让大家看到效果,我显示调用的GC.Collect()方法,让GC立刻释放内存,但是频繁的调用GC.Collect()方法会降低程序的性能,除非我们程序中某些操作占用了大量内存需要马上释放,才可以显示调用。下面是官方文档中的说明:垃圾回收GC类提供GC.Collect方法,您可以使用该方法让应用程序在一定程度上直接控制垃圾回收器。通常情况下,您应该避免调用任何回收方法,让垃圾回收器独立运行。在大多数情况下,垃圾回收器在确定执行回收的最佳时机方面更有优势。但是,在某些不常发生的情况下,强制回收可以提高应用程序的性能。当应用程序代码中某个确定的点上使用的内存量大量减少时,在这种情况下使用GC.Collect方法可能比较合适。例如,应用程序可能使用引用大量非托管资源的文档。当您的应用程序关闭该文档时,您完全知道已经不再需要文档曾使用的资源了。出于性能的原因,一次全部释放这些资源很有意义。有关更多信息,请参见GC.Collect方法。在垃圾回收器执行回收之前,它会挂起当前正在执行的所有线程。如果不必要地多次调用GC.Collect,这可能会造成性能问题。您还应该注意不要将调用GC.Collect的代码放置在程序中用户可以经常调用的点上。这可能会削弱垃圾回收器中优化引擎的作用,而垃圾回收器可以确定运行垃圾回收的最佳时间。理解C#垃圾回收机制我们首先说一下CLR(公共语言运行时,Common Language Runtime)它和Java虚拟机一样是一个运行时环境,核心功能包括:内存管理、程序集加载、安全性、异步处理和线程同步。CTS(Common Type System)通用类型系统,它把.Net中的类型分为2大类,引用类型与值类型。.Net中所有类型都间接或直接派生至System.Object类型。所有的值类型都是System.ValueType的子类,而System.ValueType本身却是引用类型。托管资源:由CLR管理的存在于托管堆上的称为托管资源,注意这里有2个关键点,第一是由CLR管理,第二存在于托管堆上。托管资源的回收工作是不需要人工干预的,CLR会在合适的时候调用GC(垃圾回收器)进行回收。非托管资源:非托管资源是不由CLR管理,例如:Image Socket, StreamWriter, Timer, Tooltip, 文件句柄, GDI资源, 数据库连接等等资源(这里仅仅列举出几个常用的)。这些资源GC是不会自动回收的,需要手动释放。通过上面的讲述总结一下,第一,GC(垃圾回收器)只回收托管资源,不回收非托管资源。第二,GC回收是要在合适的时候(CLR觉得应该进行回收的时候)才进行回收。那么非托管如何进行回收呢?下面就让我一一道来。在.Net中释放非托管资源主要有2种方式,Dispose,FinalizeDispose方法,对象要继承IDisposable接口,也就会自动调用Dispose方法。复制代码代码如下:Class Suifeng:System.IDisposable #region IDisposable 成员 public void Dispose() / #endregionSuifeng suiFeng= new Suifeng ();suiFeng.Dispose();/也可以使用Using语句(using Suifeng suiFeng= new Suifeng() /Finalize()方法MSDN上的定义是允许对象在“垃圾回收”回收之前尝试释放资源并执行其他清理操作。它的本质就是析构函数复制代码代码如下:class Car Car() / destructor / cleanup statements. 该析构函数隐式地对对象的基类调用 Finalize。 这样,前面的析构函数代码被隐式地转换为以下代码:复制代码代码如下:protected override void Finalize() try / Cleanup statements. finally base.Finalize(); 在.NET中应该尽可能的少用析构函数释放资源,MSDN2上有这样一段话:实现 Finalize 方法或析构函数对性能可能会有负面影响,因此应避免不必要地使用它们。用 Finalize 方法回收对象使用的内存需要至少两次垃圾回收。当垃圾回收器执行回收时,它只回收没有终结器的不可访问对象的内存。这时,它不能回收具有终结器的不可访问对象。它改为将这些对象的项从终止队列中移除并将它们放置在标为准备终止的对象列表中。该列表中的项指向托管堆中准备被调用其终止代码的对象。垃圾回收器为此列表中的对象调用 Finalize 方法,然后,将这些项从列表中移除。后来的垃圾回收将确定终止的对象确实是垃圾,因为标为准备终止对象的列表中的项不再指向它们。在后来的垃圾回收中,实际上回收了对象的内存。所以有析构函数的对象,需要两次,第一次调用析构函数,第二次删除对象。而且在析构函数中包含大量的释放资源代码,会降低垃圾回收器的工作效率,影响性能。所以对于包含非托管资源的对象,最好及时的调用Dispose()方法来回收资源,而不是依赖垃圾回收器。 在一个包含非托管资源的类中,关于资源释放的标准做法是: 继承IDisposable接口; 实现Dispose()方法,在其中释放托管资源和非托管资源,并将对象本身从垃圾回收器中移除(垃圾回收器不在回收此资源); 实现类析构函数,在其中释放非托管资源。 请看MSDN上的源码复制代码代码如下:Public class BaseResource:IDisposable PrivateIntPtr handle; / 句柄,属于非托管资源 PrivateComponet comp; / 组件,托管资源 Privateboo isDisposed = false; / 是否已释放资源的标志 PublicBaseResource /实现接口方法 /由类的使用者,在外部显示调用,释放类资源 Public void Dispose() Dispose(true);/ 释放托管和非托管资源 /将对象从垃圾回收器链表中移除, / 从而在垃圾回收器工作时,只释放托管资源,而不执行此对象的析构函数 GC.SuppressFinalize(this); /由垃圾回收器调用,释放非托管资源 BaseResource() Dispose(false);/ 释放非托管资源 /参数为true表示释放所有资源,只能由使用者调用 /参数为false表示释放非托管资源,只能由垃圾回收器自动调用 /如果子类有自己的非托管资源,可以重载这个函数,添加自己的非托管资源的释放 /但是要记住,重载此函数必须保证调用基类的版本,以保证基类的资源正常释放 Protectedvirtual void Dispose(bool disposing) If(!this.disposed)/ 如果资源未释放 这个判断主要用了防止对象被多次释放 If(disposing) Comp.Dispose();/ 释放托管资源 closeHandle(handle);/ 释放非托管资源 handle= IntPtr.Zero; this.disposed= true; / 标识此对象已释放 System.gc()指的是什么意思?调用垃圾回收机制,释放资源finalize方法可以用来做什么?Finalize方法用来释放资源,通过两个事例描述C+,Java不同的内存回收机制。很久很久以前,每家每户“自扫门前雪”,自己收垃圾。现在,环保局的垃圾车自动收垃圾。通过,这些例子类比Java和C+不同的回收机制及特点。第六章 异常机制Java中,处理异常的两大步是?java中常见的异常有: NullPointerException(空指针异常) ClassCastException(类型强制转换异常) ArrayindexOutOfBoundsException(数组下标越界异常) NumberFormatException(字符串转换为数字异常) IOException(输入输出异常) FileNotFoundException(文件未找到异常) NoSuchMethodException(方法未找到异常)NullPointerException: 简单地说就是调用了未经初始化的对象或者是不存在的对象,特别是对于数组,数组的初始化是对数组分配需要的空间,而初始化后的数组,其中的元素并没有实例化,依然是空的,所以还需要对每个元素都进行初始化(如果要调用的话)。ClassCastException: 强制类型转换分为基本数据类型转换和引用数据类型转换两种,对于引用数据类型来说,一般就是把父类型转换成子类型(因为子类型比父类型的内容丰富),但不是所有的父类型都可以转换子类型,例如:Object jpanel=new JPanel();JButton jpa

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论