Java:关于错误: 类 a 是公共的, 应在名为 a.java 的文件中声明

原代码:

public class A
{
	public static void main(String[] args){
		System.out.println("hallo world!");
		System.out.println("第一个java程序");
	}
}

问题截图:

在这里插入图片描述

解决方法:

这是命名错误 。
1:把文件名改为 A.java
2:把公共的(public)去掉 (见代码注释)

public class A//这里的public删除
{
	public static void main(String[] args){
		System.out.println("hallo world!");
		System.out.println("第一个java程序");
	}
}

结论:

public类可以没有,但是如果有的话,public修饰的类名必须与源文件名保持一致;并有且仅有一个!!

  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
超级有影响力的Java面试题大全文档 1.抽象: 抽象就是忽略一个主题与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承:  继承是一种联结的层次模型,并且允许和鼓励的重用,它提供了一种明确表述共性的方法。对象的一个新可以从现有的派生,这个过程称为继承。新继承了原始的特性,新称为原始的派生(子),而原始称为新的基(父)。派生可以从它的基那里继承方法和实例变量,并且可以修改或增加新的方法使之更适合特殊的需要。 3.封装:  封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 4. 多态性:  多态性是指允许不同的对象对同一消息作出响。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了用程序函数同名问题。 5、String是最基本的数据型吗?  基本数据型包括byte、int、char、long、float、double、boolean和short。  java.lang.String是final型的,因此不可以继承这个、不能修改这个。为了提高效率节省空间,我们应该用StringBuffer 6、int 和 Integer 有什么区别  Java 提供两种不同的型:引用型和原始型(或内置型)。Int是java的原始数据型,Integer是java为int提供的封装Java为每个原始型提供了封装。 原始型 封装 boolean Boolean char Character byte Byte short Short int Integer long Long float Float double Double  引用型和原始型的行为完全不同,并且它们具有不同的语义。引用型和原始型具有不同的特征和用法,它们包括:大小和速度问题,这种型以哪种型的数据结构存储,当引用型和原始型用作某个的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始型实例变量的缺省值与它们的型有关。 7、String 和StringBuffer的区别  JAVA平台提供了两个:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String提供了数值不可改变的字符串。而这个StringBuffer提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用 StringBuffers来动态构造字符数据。 8、运行时异常与一般异常有何异同?  异常表示程序运行过程可能出现的非正常状态,运行时异常表示虚拟机的通常操作可能遇到的异常,是一种常见运行错误java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 9、说出Servlet的生命周期,并说出Servlet和CGI的区别。  Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。 与cgi的区别在于servlet处于服务器进程,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。 10、说出ArrayList,Vector, LinkedList的存储性能和特性  ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。 11、EJB是基于哪些技术实现的?并说出SessionBean和EntityBean的区别,StatefulBean和StatelessBean的区别。 EJB包括Ses
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? 答: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一个题目写两页纸写的太详细,所以以上答案有的可能比较简短,没有说出重点,请大家补充,如果大家有什么更好的答案请拿出来一起分享
Java高级程序设计 第1章 Java编码规范 1.1 用场景1.2 相关知识1.3 任务实施1.4 拓展知识1.5 拓展训练1.6课后小结 Java高级程序设计实战教程第一章-Java编码规范全文共13页,当前为第1页。 1.1 用场景 一个大型的软件项目是由一个团队来完成的,每个程序员在给包、、 变量、方法取名的时候,如果根本没有一点约定,只是随心所欲,可能会带来一系列问题。 编码规范是程序编码所要遵循的规则,保证代码的正确性、稳定性、可读性。规范编码有以下作用。 一、规范的代码可以促进团队合作 二、规范的代码可以减少bug处理 三、规范的代码可以降低维护成本 四、规范的代码有助于代码审查 五、养成代码规范的习惯,有助于程序员自身的成长 Java高级程序设计实战教程第一章-Java编码规范全文共13页,当前为第2页。 1.2 相关知识 1.2.1 文件后缀名 1.2.2 源文件样式约定 1.2.3 注释规范 1.2.4 命名规范 Java高级程序设计实战教程第一章-Java编码规范全文共13页,当前为第3页。 1.2.1 文件后缀名 表1-1 Java程序使用的文件后缀名 文件文件后缀名 Java文件 .java Java字节码文件 .class 其两者最本质的区别在于,.Java文件是供虚拟机运行时执行的文件, 而.class文件可以让你在任何一台安装了Java虚拟机的机器上运行。 Java高级程序设计实战教程第一章-Java编码规范全文共13页,当前为第4页。 1.2.2 源文件样式约定 Java文件必须按顺序由以下3部分组成。 1、版权信息。 2、包和引入语句。 3、和接口声明。 1. 版权信息 版权和版本信息必须在Java文件的开头,其他不需要出现在javadoc的信息也可以包含在这里。 2. 包和引入语句 package 行要在import行之前,import 标准的包名要在本地的包名之前,而且按照字母顺序排列。如果 import 行包含了同一个包的不同子目录,则应该用 * 来处理。 3. 和接口声明 每个Java文件都包含一个单一的公共或接口。 Java高级程序设计实战教程第一章-Java编码规范全文共13页,当前为第5页。 1.2.3 注释规范 1.注释编写的原则 (1)注释形式统一。 在整个用程序,使用具有一致的标点和结构的样式来构造注释。如果在其他项目发现它们的注释规范与这份文档不同,按照这份规范写代码,不要试图在既成的规范系统引入新的规范。 (2)注释内容准确简洁。 内容要简单、明了、含义准确,防止注释的多义性,错误的注释不但无益反而有害。 2.注释型的基本划分 (1)基本注释必须要添加,包括以下几种: 1、(接口)的注释; 2、构造函数的注释; 3、方法的注释; 4、全局变量的注释; 5、字段/属性的注释; 简单的代码做简单注释,注释内容不大于10个字即可,另外,持久化对象或VO对象的getter、setter方法不需加注释。 (2)特殊必加的注释包括以下几种: 1、典型算法必须有注释。 2、在代码不明晰处必须有注释。 3、在代码修改处加上修改标识的注释。 4、在循环和逻辑分支组成的代码加注释。 5、为他人提供的接口必须加详细注释。 具体的注释格式自行定义,要求注释内容准确简洁。 3.注释的格式 (1)单行(single-line)注释格式为"//……"。 (2)块(block)注释格式为"/*……*/"。 (3)文档注释格式为"/**……*/"。 (4)Javadoc注释标签语法如下: @author 对的说明,标明开发该模块的作者; @version 对的说明,标明该模块的版本; @see 对、属性、方法的说明,参考转向,也就是相关主题; @param 对方法的说明,对方法某参数的说明; @return 对方法的说明,对方法返回值的说明; @exception 对方法的说明,对方法可能抛出的异常进行说明。 Java高级程序设计实战教程第一章-Java编码规范全文共13页,当前为第6页。 1.2.4 命名规范 命名指系统对包名、目录(名)、方法、常量、变量等标识符的命名。标识符的命名力求做到统一、达意、简洁,遵循驼峰法则。 统一是指对于同一个概念,在程序用同一种表示方法。例如对于供商,既可以用supplier,也可以用provider,但是我们只能选定一个使用,至少在一个Java项目保持统一。 达意是指标识符能准确地表达出它所代表的意义,如newSupplier, OrderPaymentGatewayService等;而 supplier1, service2,idtts等则不是好的命名方式。 简洁是指,在统一和达意的前提下,用尽
面向对象编程的基础 要了解面向对象编程(OOP)的基本概念,需要理解 OOP 的三个主要概念,它们撑起 了整个 OOP 的框架。这三个概念是:封装、继承性和多态性。除此以外,还需了解对象、 、消息、接口、及抽象等概念。 2.2.1 对象 现实世界的对象具两个特征:状态和行为。例如:自行车有状态(传动装置、步度、 两个车轮和齿轮的数目等)和行为(刹车、加速、减速和换档等)。 其次,我们再来看看软件对象。软件对象是现实世界对象的模式化产物,他们也有状态 和行为。软件对象把状态用数据表示并存放在变量里,而行为则用方法实现。实际上,软件 对象还包括了数据结构和使用这些数据结构的代码。因此也可以说:软件对象是现实世界客 观事务的软件化模拟,是变量(数据和数据结构)和相关方法(对数据操作和对象管理的程 序)的软件组合。 在面向对象的程序设计,你可以用软件对象表示现实世界的对象,而这些软件对象和 现实世界对象是相对的。例如:如果你正在建立一个帐户管理系统,那么你的对象就是帐 户、欠款、信用卡、月收入、贷款、交易等等。如果你设计一个电子实习交通工具系统,那 么你的对象就是汽车、摩托车、自行车等等。就自行车的软件对象而言,表示该对象的状态 和行为为与变量和方法相对。自行车的状态:数度是 10mp(每小时 10 米),步度是 90rpm (每分钟 90 转),当前传动装置是第 5 个齿轮。再面向对象的程序设计,这些数据放在 变量。自行车的行为:刹车,改变步度和换档。在面向对象的程序设计,这些行为用方 法实现。 在 OOP 技术,对象充当了一个很重要的角色。对象的数据是组成对象的核心,而方法 则环绕这个核心并隐藏在对象之。 2.2.2 封装 "封装"是 OOP 语言的优点之一。把一个对象的数据加以包装并置于其方法的保护之下 称为封装。所谓封装就是对数据的隐藏。封装实现了把数据和操作这些数据的代码包装成为 一个对象(即离散的部件),而数据和操作细节(方法)隐藏起来。如果增加某些限制,使 得对数据的访问可按照统一的方式进行,那些能比较容易地产生更为强壮的代码。 OOP 语言提出一种(或称为协议),以保证对数据进行统一的操作。通常的做法是:程 序和对象数据的交互作用通过一个公开的接口进行,而不直接进行操作。由于把数据封装在 对象,所以,访问对象的数据只有一种途径,那就是利用一个公开的接口。 实际上,封装在程序和数据之间设置了一道栅栏,它可以阻止一部分的设计错误,不至 于涉足用程序其他部分的数据。 2.2.3 消息 一个单独的对象一般不十分有用,而作为一员出现在包含有许多其他对象的大程序或 用程序之,通过这些对象的相互作用,程序员可实现高层次的操作和更负责的功能。某此 对象通过向其他对象发送消息与其他对象进行交互作用和通信。 消息是以参数的形式传递给某方法的。一个消息通常由三部分组成: 1. 消息传送到对象的名称。 2. 要执行的方法的名称。 3. 方法需要的任意参数。 2.2.4 是一个蓝图或样板,定义了某种型的所有对象的变量和方法。 在 java 语言Java 程序的基本单位是,也就是说:一个 Java 程序是由多个组成 的。定义一个与定义一个数据型是有区别的。在程序设计语言,把定义数据型的能 力作为一种很重要的能力来对待。在面向对象的语言的功能更强大,这是因为不仅 含有定义数据型的功能,而且还包含了对方法的定义。 对象实际是的一个实例。生成实例的过程叫做把"一个对象实例化"。一个实例化 的对象实际上是由若干个实例变量和实例方法组成的。当你创建出一个的实例时,系统将 为实例变量指定内存,然后你就可以利用实例方法去做某些事情。 2.2.5 继承 继承是指建立子的能力。子继承了父亲的特征和功能。的层次结构似于一棵数 的结构,也像一个家庭谱系。它显示了根和它的导出之间的关系。 子从它先辈那里继承了代码和数据,这样,它就可以执行先辈的功能和访问先辈 的数据。一个纯面向对象程序设计的语言将具有严格的继承性。 通过对象、,我们实现了封装,通过子我们可以实现继承。例如,公共汽车、出租 车、货车等都是汽车,但它们是不同的汽车,除了具有汽车的共性外,它们还具有自己的特 点(如不同的操作方法,不同的用途等)。这时我们可以把它们作为汽车的子来实现,它们 继承父(汽车)的所有状态和行为,同时增加自己的状态和行为。通过父和子,我们实 现了的的层次,可以从最一般的开始,逐步特殊化,定义一系列的子。同时,通过继 承也实现了代码的复用,使程序的复杂性线性地增长,而不是呈几何级数增长。 2.2.6 抽象 面向对象的程序设计系统鼓励充分利用"抽象"。在现实世界,人们正是通过抽象来 理解复杂的事务。例如:人们并没有把汽车当作成百上千的零件组成来认识,而是把它当作 具有自己特定行为的对象。人们可以忽略发动机、液压传输、刹车系统等如何工作的细节, 而习惯于把汽车当作一个整体来认识。 包含通用对象的库叫作库。 2.2.7 多态型 面向对象程序的最后一个概念是多态性。凭借多态性,你可以创建一个新的对象,它具 有与基对象相同的功能,但是这些功能的一个或多个是通过不同的方式完成的。例如:在 Java 你可以凭借多态性,通过一个画圆的对象,来创建一个画椭圆或矩形的对象。不管是 画圆,画椭圆还是画矩形的方法,它们都有一个相同的方法名,但以不同的方式完成他们的 画圆的功能。 1.8 和对象 1.8.1 是组成 Java 程序的基本要素。它封装了一对象的状态和方法,是这一对象的 原型。定义一个,实际上就是指定该所包含的数据和对数据进行操作的代码。 通过关键字 class 来定义,一般格式为: 【说明修饰符】class 名【extends 子句】【implements 子句】 type instance-varable1; type instance-varable2; type instance-varable3; the methodname1(parameter-list){method-body;} the methodname2(parameter-list){method-body;} the methodnameN (parameter-list){method-body;} 下面将定义格式的项目说明如下: (1) class 是说明关键字。 (2) 名是由程序员自己定义的 Java 标识符,每个说明必须有 class 和名。 (3) 说明修饰符包括:  abstract 说明一个为抽象,抽象是指不能直接实例化对象的。  final 说明一个为最终,即改不能再有子。  public 说明公共,该可以被当前包以外的和对象使用。  private 说明为私有。 (4) extends 子句用于说明的直接超。 (5) implements 子句用于说明将实现哪些接口,接口是 Java 的一种引用 型。 (6) 体包含了变量和方法。在定义的数据、变量和方法称为的成员, 或称为实例变量和实例方法。 (7) 例如: 下例定义了一个 Point ,并且声明了它的两个变量 x、y 坐标 ,同时实现 init()方法 对 x、y 赋初值 。 class Ponit { int x,y; void init(int ix, int iy){ x=ix; y=iy; } } 所定义的变量和方法都是的成员。对的成员可以设定访问权限 ,来限定 其它对象对它的访问,访问权限所以有以下几种:private, protected, public, friendly。 1.8.2 对象 把实例化,我们可以生成多个对象,这些对象通过消息传递来进行交互(消息 传递即激活指定的某个对象的方法以改变其状态或让它产生一定的行为),最终完 成复杂的任务。一个对象的生命期包括三个阶段:创建对象、对象的引用和释放对 象 。 1.8.3 创建对象 创建对象包括声明、实例化和初始化三方面的内容。通常的格式为 : 1. 声明对象 对象声明实际上是给对象命名,也称定义一个实例变量。对象声明的一般格式为: type name 其,type 是一个名,用它声明的对象将属于改;name 是对象名。 例如: Date today; Rectangle myRectangle; 第一条语句说明了对象 today 属于 Date ,第二条语句说明了对象 myRectangle 属于 Rectangle 。对象说明并没有体现一个具体的对象,只有通过实例化后的对 象才能被使用。 2. 实例化对象 实例化对象就是创建一个对象。实例化对象意味着给对象分配必要的存储空间,用 来保存对象的数据和代码。实例化后的每个对象均占有自己的一块内存区域,实例 化时,每个对象分配有一个"引用"(reference)保存到一个实例变量。"引用" 实际上是一个指针,此指针指向对象所占有的内存区域。 因此,对象名(变量)实际上存放的是一个被实例化之后的对象所占有的内存区域 的指针。 例如: type objectName = new type ( [paramlist] ); 运算符 new 为对象分配内存空间 ,实例化一个对象 。new 调用对象的构造方法,返 回对该对象的一个引用(即该对象所在的内存地址)。用 new 可以为一个实例化, 多个不同的对象。这些对象分别占用不同的内存空间,因此改变其一个对象的状 态不会影响其它对象的状态 。 3.初始化对象 生成对象的最后一步是执行构造方法,进行初始化。由于对构造方法可以进行重写 ,所以通过给出不同个数或型的参数会分别调用不同的构造方法。 例子:以 Rectangle 为例,我们生成 Rectangle 的对象: Rectangle p1=new Rectangle (); Rectangle p2=new Rectangle (30,40); 这里,我们为 Rectangle 生成了两个对象 p1、p2,它们分别调用不同的构造方法, p1 调用缺省的构造方法(即没有参数),p2 则调用带参数的构造方法。p1、p2 分别对 于不同的内存空间,它们的值是不同的,可以完全独立地分别对它们进行操作。虽 然 new 运算符返回对一个对象的引用,但与 C、C++的指针不同,对象的引用是指 向一个间的数据结构,它存储有关数据型的信息以及当前对象所在的堆的地址, 而对于对象所在的实际的内存地址是不可操作的,这就保证了安全性。 1.8.4 对象的引用 对象的使用包括引用对象的成员变量和方法,通过运算符·可以实现对变量的访问和方法的调 用,变量和方法可以通过设定一定的访问权限(见下面的例子)来允许或禁止其它对象对它的 访问。 我们先定义一个 Point。 例子: class Point{ int x,y; String name = "a point"; Point(){ x = 0; y = 0; } Point( int x, int y, String name ){ this.x = x; this.y = y; this.name = name; } int getX(){ return x; } int getY(){ return y; } void move( int newX, int newY ){ x = newX; y = newY; } Point newPoint( String name ){ Point newP = new Point( -x, -y, name ); return newP; } boolean equal( int x, int y ){ if( this.x==x && this.y==y ) return true; else return false; } void print(){ System.out.println(name+" : x = "+x+" y = "+y); } } public class UsingObject{ public static void main( String args[] ){ Point p = new Point(); p.print(); //call method of an object p.move( 50, 50 ); System.out.println("** after moving **"); System.out.println("Get x and y directly"); System.out.println("x = "+p.x+" y = "+p.y); //access variabl es of an object System.out.println("or Get x and y by calling method"); System.out.println("x = "+p.getY()+" y = "+p.getY()); if( p.equal(50,50) ) System.out.println("I like this point!!!! "); else System.out.println("I hate it!!!!! "); p.newPoint( "a new point" ).print(); new Point( 10, 15, "another new point" ).print(); } } 运行结果为: C:\java UsingObject a point : x = 0 y = 0 **** after moving ***** Get x and y directly x = 50 y = 50 or Get x and y by calling method x = 50 y = 50 I like this point!!!! a new point : x = -50 y = -50 another new point : x = 10 y = 15 1.引用对象的变量 要访问对象的某个变量,其格式为: objectReference.variable 其 objectReference 是对象的一个引用,它可以是一个已生成的对象,也可以是能够生成对 象引用的表达式。 例如:我们用 Point p=newPoint();生成了 Point 的对象 p 后,可以用 p.x,p.y 来访问该点的 x、y 坐标,如 p.x = 10; p.y = 20; 或者用 new 生成对象的引用,然后直接访问,如: tx=new point().x; 2.调用对象的方法 要调用对象的某个方法,其格式为: objectReference.methodName ( [paramlist] ); 例 如我们要移动 Point 的对象 p,可以用 p.move(30,20); 虽然我们可以直接访问对象的变量 p.x、p.y 来改变点 p 的坐标,但是通过方法调用的方 式来实现能更好地体现面向对象的特点,建议在可能的情况下尽可能使用方法调用。 同样,也可以用 new 生成对象的引用,然后直接调用它的方法,如 new point(). move (30,20); 前面已经讲过,在对象的方法执行完后,通常会返回指定型的值,我们可以合法地使 用这个值,如:例子 Point 的方法 equal 返回布尔值,我们可以用它来作为判断条件分别执 行不同的分支。如: if (p.equal (20,30)){ ...... //statements when equal }else { ...... //statements when unequal } 另外, Point 的方法 newPoint 返回该点关于原点的对称点,返回值也是一个 Point 型,我们 可以访问它的变量或调用它的方法,如: px = p.newPoint().x 或 px = p.newPoint(). getX(); 1.8.5 成员变量 对象具有状态和行为,而对象的状态则是用变量或数据来描述的。在一个,对象的 状态是以变量或数据的形式定义的。 例如: "盒子"的体积的状态主要是宽度、高度、和深度。因此在定义"盒子"对象时,只 将这三个属性作为其主要的状态,并用变量的形式来描述,这些变量称为成员变量。而在对 象实例化后,这些变量称为实例变量。 1.8.6 成员变量定义格式 成员变量定义的一般格式为: 【Modifer】type variablelist; 其, type 指定变量的型,它可以时 Java 的任意一种型。 variablelist 是一组逗号隔开的变量名(变量列表),每个变量都可带有自己的初始化的表达 式。 例如: xint ,z; aint ,b=2,c=3; Modifer 是定义变量的修饰符,它说明了变量的访问权限和某些使用规则。变量修饰符可以 是关键字 public、protected、private、final、static、transient 和 volatile 的组合。 1.8.7 成员变量的初始化 当成员变量含有自己的初始化表达式时,可以创建实例的方式使成员变量实例化。 例如: class Box{ double width = 10; double height= 15; double depth= } 变量 width、height、depth 是成员变量。在执行 Box myBox1 = new Box()语句之后, new 运算符就创建了一个实例,并将变量分别赋初值为 10、15、20。在此时的变量 width、 height、depth 称为实例变量。 注意:在初始化表达式,不能包含成员变量本身或同的其他成员变量。例如,下面 的用法式错误的: class Test{ int int t =j; int } 错误有两个:一个式变量 k 的初始化涉及对 k 自身的访问;二式对 t 进行初始化时含有 对 j 的访问,而 j 的说明在其后。 1.8.8 成员变量的访问权限 成员变量或方法的访问权限是用访问权限修饰符来指定的。Java 的访问权限修饰符包括四种 显示方式修饰符和一种隐含方式修饰符,即: 1. 公用变量 用 public 说明的变量是公有变量。 访问权限:允许任何包的任何的变量访问。 例如:下面的代码,在 Alpha 说明了一个公用变量 i_public,而在另一个 Beta 可以访问该变量。 class Alpha{ public int i_public ; } class Beta{ void accessmethod() { Alphaa= newAlpha(); a.i_public=10; } } 2. 私有变量 //说明公用变量 i_public //访问公用变量 i_public 用 private 说明的变量是私有变量。 访问权限:只能被定义它的的变量访问。 例如:下面的代码,在 Alpha 说明了一个私有变量 i_private,其他不允 许访问。 正确的访问格式: class Alpha{ 3. 保护变量 } public int i_private ; void accessmethod() { Alphaa= newAlpha(); a.i_private=10; } //说明私有变量 i_private //访问私有变量 i_private 用 protected 说明的变量是保护变量。 访问权限:允许自身、子以及在同一个包的所有的变量访问。 例如:假定某个包 Geek 含有两个成员 Alpha 和 Beta,若在 Alpha 说明 了一个保护变量 i_protected,则在另外一个 Beta 可以访问该变量。 class Alpha{ public int i_protected; void accessmethod() } class Beta { void accessmethod() { Alpha a= new Alpha(); a.i_protected=10; } } 4. 私有保护变量 //说明保护变量 i_protected //访问保护变量 i_protected 用 private protected 说明的变量是私有保护变量。 访问权限:允许自身以及它的子变量访问。 例如:下面的两种访问方式是可行的。 (1) 在访问私有保护变量 例如: class Alpha{ private protected int i_pri_prot ; void accessmethod() { Alphaa= newAlpha(); } } a. i_pri_prot =10; //访问私有保护变量 i_pri_prot (2) 在子访问私有保护变量 例如: class Alpha{ private protected int i_pri_prot=10 ; } class Beta extends Alpha { void accessmethod() { Alphaa= newAlpha(); } } a. i_pri_prot =30; //访问私有保护变量 i_pri_prot 在程序执行时,变量 i_pri_prot 的值是 30,而不是 10; 5. 友好变量 如果一个变量没有显示地设置访问权限,则该变量为友好变量。 访问权限:允许自身以及在同一个包地所有地变量访问。 例如:下面的定义了一个友好变量: class Alpha{ int i_friendly ; void accessmethod() { Alphaa= newAlpha(); } } a. i_friendly=10; //访问友好变量 i_friendly 在了解了成员变量的访问权限之后,那么在说明每一个成员变量时,都可以按访问权限给变 量提供适当的保护措施,这样就加强了变量的安全性。 名称 公用 私有 保护 私有保护 访问权限修饰 public private protected private protected √ √ √ √ 子 √ √ √ 包 √ * 所有 √ √ 友好 friendly √ √ 注:表√的为可选,打*的说明有特殊限制。*号是针对子访问保护变量而言,即一个子只有与超 在同一个包,才可以访问超对象的保护变量。 1.8.9 静态变量 用 static 说明的变量是静态变量。静态变量与其他成员变量有区别:其他成员变量必须通过 的对象来访问,每个对象都有这些变量的备份;而静态变量独立于改的任何对象,它 在的实例只有一个备份,可以直接使用,而不必通过的对象去访问,它一直属于定义 它的,因此也称为变量。的所有对象都共享 static 变量。static 变量通常也称为全局变 量。 例如: 静态变量的定义和引用。首先在 MyDemo 定义了 static 变量 x,y 然后在 MyStaticDemo 输入变量 x 和 y 的值。 import java.awt.Graphics; class MyDemo { static int x=80; static int y=120; } class MyStaticDemo extends java.applet.Applet { public void paint(Graphics g) { g.drawString("x="+MyDemo.x+"y="+MyDemo.y,25,50); } } 程序运行结果: x=80 y=120 在上面的程序,在访问的静态变量 x 和 y 时,是通过名 MyDemo 直接访问的。 static 也可以说明方法。用 static 说明的方法是静态方法或方法,在实例只有一 个备份。该方法具有以下约束: a) b) c) 它们仅可以调用其他 static 方法。 它们仅可以访问 static 变量。 它们不能参考 this 或 super。 如果的成员被定义为 static,则可以通过下面形式引用: 名,成员名 这里,名是定义 static 成员所属的Java 通过这样的方式,实现了全局方法和变量。 1.8.10 final 变量 用 final 说明的变量可以当作一个常量使用,不得对其进行任何修改。若某此变量为了 防止被修改,则定义变量时必须初始化一个 final 变量。在这一点上,final 与 C\C++的 const 相似。比如: final int MONDAY=1; final int TUSDAY=2; final int WEDNESDAY=3; ...... 以后程序可以把上述变量当作常量来使用,而不用担心其被修改。 final 变量用大写字母来表示,这是一种习惯约定。final 变量不占内存空间,实际上也 就是一个常数。 1.9 方法 1.9.1 方法的定义 方法也是的一个成员,定义方法时在定义的同时进行的。其一般格式为: type name(parameter -list) { //方法体 } 格式说明: (1) type 指定方法的返回型,简称方法的型,它可以是任何有效的型, 包括型。方法的返回或带值返回都由 return 语句实现,当一个方法没 有返回值时,其 type 必须为 void,且 return 语句可以省略。 (2) name 指定方法名,方法名可以是合适的 Java 标识符。 (3) parameter-list 指定方法的参数列表,参数包括参数的型和参数名,每个 参数用逗号隔开。在定义方法时,其参数将作为形参;在调用方法时,其 参数被称为实参。调用时是把实参的值传递给形参。入过方法没有参数, 参数列表为空,但括号"()"不能省略。 (4) 方法体包含了一组代码,它用于对数据处理。方法体用以对大括号"{}"括 起来。 例如:Box 封装"盒子"的状态和行为,即数据变量和方法,用方法 volume 计 算 Box 对象的体积。 import java.awt.Graphics; class Box { double width; double height; double depth; void setDemo(double w,double h,double d) { width=w; height=h; depth=d; } } double volume() { return width*height*depth; } class BoxDemo extends java.applet.Applet { public void paint(Graphics g) { double d_volume; Box myBox = new Box(); myBox.setDemo(10,20,30); //调用方法 setDemo 给变量赋值 d_volumn = myBox.volume(); //计算体积 g.drawString("myBox 的体积是:"+ d_volumn,25,50); } } 程序运行的结果如下: myBox 的体积是:6000 1.9.2 方法的访问权限 方法同成员变量一样,可以在定义时说明方法的访问权限,其说明格式和访问机制与成 员变量完全一样。 例如:私有方法、私有保护方法只能被同一个的方法调用,公用方法可以被其他 的方法调用。 import java.awt.Graphics; class Alpah1 { pivateint i_private() { int x=10; int y=20; return x+y; } public int i_public1() { return i_private(); } } class Alpah2 { public public int x,y; private protected int i_protected(int a,int h) { x=a; y=b; return x+y; } public void i_public2(int i,int j) { k=i_protected(i,j); } } class Test extends java.applet.Applet { public void paint(Graphics g) { int p1; Alpah1 ap1= newAlpah1(); Alpah2 ap2= newAlpah2(); p1=ap1.i_public1(); ap2. i_public2(50,50); g.drawString("i_public1()的返回值是:"+p1,25,50); g.drawString("i_public2()的返回值是:"+ap2.k,25,50); } } 程序运行的结果如下: 方法 i_public1()的返回值是:30 方法 i_public2()的返回值是:100 程序说明: (1)在 Alpah1 ,方法 i_private()是私有的,它只能被同的方法 i_public1()调用。 而方法 i_public1()是公有的,它可以被另一 Demo 的方法 paint()调用。 (2)在 Alpah2 ,方法 i_protected()是私有保护性的,它不能被其他的方法调用, 而只能被同(或子)的方法 i_public2()调用。同样,方法 i_public2()也是公有的,它可 以被另一 Test 的方法 paint()调用。 (3)在方法 i_public1(),语句 return i_private()执行的顺序为:先调用,后返回。其 返回值是 x+y 的和。 (4)在方法 i_public2(int i,int j),将形参 i 和 j 作为调用方法的实参。 如:k=i_protected(i,j); (5) 在 Alpha2 ,定义了成员变量 k、x 和 y。其 k 是公有的,它可被 Test 的方法引用,其格式为:ap2.k;而变量 x 和 y 是私有的。它只能被同一的方法引用。 (6)在 Alpah1 方法 i_private(),定义的变量 x 和 y 是局部变量。 局部变量作用域是:只能在定义它的方法有效,即使同一的方法也不能引用。 例如:方法 i_public()是不能访问局部变量 x 和 y 的。 1.9.3 对象作为参数 例:给定两个数,按大小顺序输出。 import java.awt.Graphics; class Test1 { public int a,b; void mov(int i,int j) { a=i; b=j; } } class Test2 { void max(Test1 test1) { int c; if(test1.a<test1.b) { c=test1.a; 引用 test1 对象的成员变量 a。 test1.a = test.b; test1.b=c; } } } class MaxTest extends java.awt.Applet { public void paint(Graphics g) { Test1myTest1=new Test1(); Test2 myTest2 = new Test2(); myTest1.mov(45,55); //调用 Test2 的方法 max,并将对象 myTest1 作为实参。 myTest2.max(myTest1); g.drawString("大小顺序为:"+ myTest1.a+","+myTest1.b,25,50); } } 1.9.4 对象作为返回值 下面的例子是把对象作为返回值的编程方法。 例如:利用方法返回对象的特性,实现对实例变量的值的递增。 import java.awt.Graphics; class Test { public int a,b; void mov( int i,int j) { a=i; b=j; } Test max() //方法 max()的返回值型是 Test 型 { Test myTest = new Test(); myTest.mov(a+10,b+10);使实例变量的值增 10。 return myTest; } } class OutMyDemo extends java.applet.Applet; { public void paint(Graphics g) { Test p1 = new Test(); Test p2; p1.mov(15,55); g.drawString("p1 的实例变量值:a="+pa1.a+",b="+pa1.b,25,75); p2=p2.amx(); g.drawString("p2(p2 加 10)的值:a="+p2.a+",b="+p2.b,25,100); } } 程序运行的结果如下: p1 的实例变量值:a=15,b=55; p2(p1 加 10)的值:a=15,b=65; p2(p2 加 10)的值:a=35,b=75; 1.10 构造方法 1.10.1构造方法概述 构造方法是一个在创建对象初始化的方法,它具有与相同的名字。事实上,除了构造 方法,在不能再有别的方法与同名。一旦定义了构造方法,在执行 new 操作期间, 首先创建对象,然后自动调用构造方法将对象初始化。 与其他方法不同,构造方法必须在 new 运算符引用,而不能按引用一般方法的格式 去引用构造方法。 在同一个,允许定义多个构造方法。这些构造方法是以参数的个数来区分的。在创 建对象时,程序员当根据参数的个数和型来选择合适的构造方法。 如果一个没有包含构造的说明,将提供隐含的构造方法,隐含的构造方法没有参数, 它将调用超不带参数的构造方法,如果超没有不带参数的构造方法,将产生编译 误。 构造方法有些特殊,它没有返回型甚至 void。因为构造方法的缺省返回型是型 本身。构造方法的另一个特殊性是它不能继承超。 例子: import java.awt.Graphics; class Test { double width; double height; double depth; Test(double w,double h,double d) //定义构造方法 Box() { width = w; height = h; depth=d; } double volume() { return width*height*depth; } } class Testing extends java.applet.applet { public void paint(Graphics g) { double d_volume; Test test = new Test()//new 运算符创建对象 test 后,随即对 test 初始化。 } } d_volume = test.volume();//计算体积 g.drawString("test 的体积是:"+d_volume,25,50); 程序运行的结果如下: test 的体积是:6000 1.10.2构造方法的访问权限 在定义构造方法时可以对他们附加访问修饰符,它们时: pulic(公有型的构造方法) private (私有型的构造访问) proected (保护型的构造方法) private protected (私有保护型的构造方法) 这四种方法访问修饰符的权限范围和方法的访问权限的范围一样。构咱方法的访问修饰符不 能是 abstract、static、final、native 或 synchronized; 1.11 方法重载 在 java ,可以在同一个定义多个同名的方法,只要它们的参数列表不同,这叫做方 法的重载(Overload)。方法重载是 Java 最具有吸引力的有利特征。 当一个重载方法被激起时,Java 便根据参数的型和数目确定被调用的方法。这样,重载方 法之间一定具有不同的参数列表,包括参数的型和数目。 例:给定两个或三个数,将它们由大到小按顺序输出。 import java.awt.Graphics; class Test { double max1,max2,nax3; Test() { max1=-1; maxe2=-1; max3=-1; } void sort(double i,double j) { double s; max1=i; max2=j; if( max1<max2) { s=max1; max1=max2; } } max2=s; } void sort(double I,double j,double k) { double s; max1=i; max2=j; max3=k; if(max1<max2) { s=max1; max1=max2; max2=s; } if(max1<max3) { s=max1; max1=max3; max3=s; } if(max2<max3) { s=max2; max2=max3; max3=s; } } class outMaxTest extends java.awt.Applet { public void paint(Graphics g) { Testt1=new Testt(); t1.sort(200,300); g.drawString("两个数的大小顺序为:"+ t1.max1+","+t1.max2,25,10); t1.sort(100.9f,200.9f,300.9f); g.drawString("三个数的大小顺序为:"+ t1.max1+","+t1.max2+","+t1.max3,25,30); } } 程序运行的结果如下: 两个数的大小顺序为:300,200 三个数的大小顺序为:300.9,200.9,100.9 在上面的代码 Test 定义了三个方法: Test()是一个无参的构造方法,它在创建对象之后紧接着对变量进行初始化。如果没有该 方法,在创建对象时将产生编译错误。因为 Test 是直接超。 两个 sort()是排序方法,它们是用参数的数目来区分的,这两个 sort()方法能对任 何数字型的数据进行排序。当然,对多个数据进行排序最好用数组来实现。 1.12 this 1.12.1用 this 引用成员变量 例子:在构造方法使用 this,this 代表当前对象的引用参考,并将参数值赋值到成员 变量 max1、max2 和 max3 。 import java.awt.Graphics; class Test { double max1; double max2; double max3; Test(double i,double j) { this.max1=i; this.max2=j; this.max3=k; } } class Test1 extends java.awt.Applet { public void paint(Graphics g) { Test t = new Test(10,20,30); g.drawString(t.max1+","+t.max2+","+t.max3,25,30); } } 程序运行的结果如下: 10,20,30 1.12.2在构造方法用 this 调用一般方法 例子:在构造方法使用 this 调用 sort()方法。 import java.awt.Graphics; class Test { double max1,max2,max3; Test(double i,double j) { max1=i; max2=j; this.sort(i,j); //调用 sort 方法,将两个数排大小顺序。 } Test(double i,double j,double k) { max1=i; max2=j; max3=k; this.sort(i,j,k) //调用 sort 方法,将三个数排大小顺序。 } void sort(int i,double j) { double s; if(max1<max2) { s=max1; max1=max2; max2=s; } } void sort(double i,double j,double k) { double s; if(max1<max2) { s=max1; max1=max3; max2=s; } if(max1<max3) { s=max1; max1=max3; } max3=s; } } if(max2<max3) { s=max2; max2=max3; max3=s; } class ThisTest extends java.applet.Applet { public void paint(Graphics g) { Test t1 = newTest(10,100); g.drawString("两个数的大小顺序为:"+t1.max1+","t1.max2,25,10); Test t2 = new Test(100,10,1000); g.drawString("三个数的大小顺序为:"+t2.max1+","t2.max2+","+t2.max3,25,30); } } 程序运行的结果如下: 两个数的大小顺序为:100,10 三个数的大小顺序为:1000,100,10 1.12.3在方法用 this 调用另外一个方法 例子:在上面的例子上加一个方法 mov(),在 mov()引用 this 再调用 sort()方法。 import java.awt.Graphics; class Test { double max1,max2,max3; Test(double i,double j) { max1=i; max2=j; this.sort(i,j); //调用 sort 方法,将两个数排大小顺序。 } void sort(int i,double j) { double s; if(max1<max2) } { } s=max1; max1=max2; max2=s; } void mov(double i,double j) { max1=i; max2=j; this.sort(i,j); } class ThisTest extends java.applet.Applet { public void paint(Graphics g) { Test t1 = newTest(10,100); t1.mov(20,200); g.drawString("两个数的大小顺序为:"+t1.max1+","t1.max2,25,10); } } 程序运行的结果如下: 两个数的大小顺序为:200,20 注意:再初始化之后,变量 max1 和 max2 的值分别为 10 和 100,当调用 mov()之后, 其值为 20 和 200。 1.13 的继承 继承是面向对象程序设计的重要概念之一。在 java ,被继承称为超,继承称为 子。通过继承可使子继承超的特征和功能。其基本规则如下: (1) 子可继承其超的代码和数据,即在子可以直接执行超的方法和访问超 的数据。 (2) 在子可以增加超没有的变量和方法。 (3) 在子可以重新定义超已有的变量(包括实例变量和变量)。变量的重新 定义被称为变量的隐藏,也就是说,在子允许定义与超同名的变量。 (4) 在子可以重载超已有的方法(包括构造方法、实例方法和方法)。 (5) 在子的构造方法,可以通过 super()方法将超的变量初始化。 (6) 当超为抽象时,子可继承超的抽象方法,并在子去实现该方法的细 节。 1.13.1 创建子 实现继承要用 extends 关键词,其格式如下: 子名 extends 超名 (1) 继承超的方法和变量 例子:给定三个数,将它们按大到小的顺序输出。在下面的程序,子 Test1 继承超 Test 的全部代码和变量。在子的方法,调用超的方法 sort()和更 新数据。 import java.awt.Graphics; class Test { double max1,max2,max3; Test() { max1=-1 max2=-1; max3=-1; } void sort() { double s; if(max1<max2) { s=max1; max1=max2; max2=s; } if(max1<max3) { s=max1; max1=max3; max3=s; } if(max2<max3) { s=max2; max2=max3; max3=s; } } } class Test1 extends Test { void subsort(double i,doublej,double k) { max=i; max2=j; max3=k; sort(); //调用超 Test 的方法 sort() } } class SortTest extends java.applet.Applet { public void paint(Graphics g) { Test1t1 =new Test1(); t1.subsort(100,.300,200); g.drawString("三个数的大小顺序为:"+t1.max1+","t1.max2+","+t1.max3,25,30); } } 程序运行的结果如下: 三个数的大小顺序为:300,200,100 (2) 隐藏实例变量和变量 在子,若定义了与超同名的变量,则只有子的变量有效,而超 的变量无效。 例:数据求和。 import java.awt.Graphics; class Test { double sum,num1,num2; static int num3; Test() { num1=0; num2=0; num3=0; sum=0; } } class Test1 extendsTest { int sum,num1,num2; //隐藏超 Test 的实例变量 static int num3; //隐藏超 Test 变量 } void sum(int i,int j,int k) { num1=i; num2=j; num3=k; sum=num1+num2+num3; } class SumTest extends java.awt.Applet { public void paint(Graphics g) { Test1t1 =new Test1(); t1.sum(100,200,300); g.drawString("sum="+ t1.num1+"+"+t1.num2+"+"+t1.num+"="+t1.sum,25,30); } } 程序运行的结果如下: sum=100+200+300+=600 (3)访问权限 尽管子可以继承超的所有成员,但子不能继承超的私有变量和方法,而只能 继承如下变量和方法。 .超定义为公有的、私有保护的或保护的成员变量和方法可被子访问。 .同一个包的超的友好变量和方法可被子访问。 (4)用继承的方法来扩充超的功能 如果子只继承超的代码和数据是没有多大意义的,对继承来说,其真正的目的是想 通过子来扩充超来的功能,只有这样,才能有效发挥继承的作用。 例:从超 Box 只计算"盒子"的体积,但在子 SubBox 不仅只计算"盒子"的 体积,而且还能求得它重量。 import java.awt.Graphics; class Box { double width; double height; double depth; Box(double w,double h,double d) { width=w; height=h; } Box() { depth=d; } width=-1; height=-1; depth=-1; } double volume() { return width*height*depth; } class SubBox extends Box { double weight; SubBox(double w,double h,double d,double m) { width=w; height=h; depth=d; weight=m; } } class Test extends java.awt.Applet { public void paint(Graphics g) { double d_volume; Box box1=new Box(10,20,30); d_volume=box1.volume(); //计算 box1 的体积 } } g.drawString("box1 的体积是:"+d_volume,25,50); SubBox subBox = new SubBox(15,15,20,40); d_volume= subBox.volume(); g.drawString("subBox 的体积是:"+d_volume,25,75); g.drawString("subBox 的体积是:"+subBox.weight,25,90); 程序运行的结果如下: box1 的体积是:6000; subBox 的体积是:4500 subBox 的重量是:40 1.13.2 重载超的方法 要使多态性在程序设计运用成功,不仅要求超给子提供可直接使用的元素,更重要的 是在层次结构具有一致的接口,使子在超的基础上扩充超的功能。 例:超 Test 方法 sort()实现对 n 个整个升序排列,子 Test1 的 sort()实现对 n 个整数 按降序排列。 import java.awt.Graphics; class Test { int Test() { i=j=k=swap=0; } void sort(int t1,int t2[ ]) //用选择法按升序排列 { for(int i=0;i<t1-1;i++) { k=i; for(i=0;i<t1-1;j++) { if(t2[j]<t2[k]) { k=j; } if(k!=i) { swap=t2[i]; t2[i]=t2[k]; t2[k]=swap; } } } } } class Test1 extends Test { void sort(i=0;i<t1-1;i++)//重载超的方法 sort(),用选择法按降序排列 { for(int i=0;i<t1-1;i++) { k=i; for(i=0;it2[k]) { k=j; } if(k!=i) { swap=t2[i]; t2[i] =t2[k] t2[k]=swap; } } } } } class SortTest extends java.awt.Applet { public void paint(Graphics g) { int a[]={34,12,8,67,88,23,98,101,119,56}; g.drawString("排序前的数据为:",20,10); for(int i=0;i<10;i++) { g.drawString(""+a[i],20+i*30,30); } Test t1=new Test(); t1.sort(a.lenght,a); //调用 Test 的方法 g.drawString("按升序排列的数据为:",20,50); for(int i=0;i<10;i++) { } g.drawString(""+a[i],20+i*30,70); } } Test1 t2=new Test2(); t2.sort(a.lenght,a); g.drawString("按降序排列的数据为:",20,90); for(int i=0;i<10;i++) { g.drawString(""+a[i],20+i*30,110); } 程序运行的结果如下: 排序前的数据为: 34 12 8 67 88 23 98 101 119 56 按升序排列的数据为: 8 12 23 34 56 67 88 98 101 119 按降序排列的数据为: 119 101 98 67 56 34 23 12 8 1.13.3 super super 是一个方法,其格式为: super(parameter-list) 其,parameter-list 是参数列表。super()的作用是调用超的构造方法。降超的变量初 始化。super()总是用于子的构造方法,而且在子的构造方法最先执行 super().因此, 只有 parameter-list 与超的构造方法的参数相匹配,才能有效调用超的构造方法去实现 对超的变量初始化。同时,在子也减少了初始化编码的重复工作。 super()的用法请见下面的例子: 例:在下面的例子里,将子的构造方法的赋初值改用 super()方法来完成 import java.awt.Graphics; class Box { double width; double height; double depth; Box(double w,double h,double d) { width=w; height=h; depth=d; } Box() { } width=-1; height=-1; depth=-1; } double volume() { return width* height* depth; } class SubBox extends Box { double weight; SubBox(double w,double h,double d,double m) { super(w,h,d); weight=m; } } class BoxTest extends java.awt.Applet { public void paint(Graphics g) { double d_volume; Box box1=new Box(10,20,30); d_volume=box1.volume(); //计算 box1 的体积 } } g.drawString("box1 的体积是:"+d_volume,25,50); SubBox subBox = new SubBox(15,15,20,40); d_volume= subBox.volume(); //计算 subBox 的体积 g.drawString("subBox 的体积是:"+d_volume,25,75); g.drawString("subBox 的体积是:"+subBox.weight,25,90); 程序运行的结果如下: box1 的体积是:6000; subBox 的体积是:4500 subBox 的重量是:40 但要注意的是: (1) super(w,h,d)用于子的构造方法 SubBox()。 (2) super(w,h,d)的参数与超的构造方法参数相匹配,即参数个数及型 一样。 1.13.4 abstract 当要求将一个超定义为抽象时,前面加关键字 abstact。其格式如下: abstract 名{} abstract 的作用是说明该是一种抽象结构。抽象结构的包含了一些抽象的方法,而这些 抽象方法只有方法的形式,即方法体是空的,方法体的细节由子去实现。抽象方法的定义 也由关键字 abstract 来说明,其格式为: abstract 型 方法名{parameter-list}; { 其,parameter-list 是参数列表。因此,整个抽象的结构如下形式: 成员变量 1; 。。。。。 构造方法 。。。。。。 abstract 型 方法名(parameter-list); } 抽象的定义也是多态的一种体现。因为多态性具有子重载超的方法的特性,而在超 只限定子重载规定的方法,但这些方法的细节必须由子来完成。所有,常把这样的 作为抽象。 抽象不能直接用 new 运算符实例化一个对象。抽象方法只能是实例化方法,它不包括子 对象。 例:在抽象 Test ,定义一个抽象方法 sort(),并在子 Test1,Test2 ,分别去实现超 的抽象方法 sort()的细节,从而分别完成对 n 个整数的降序、升序的排列。 import java.awt.Graphics; abstract class Test { int i,j,k,swap; Test() { i=j=k=swap=0; } abstract void sort(int t1,int[] t2); //定义一个抽象的方法。 } class Test1 extends Test { void sort(int t1,int t2[ ]) //重载超的方法 sort(),用选择法按降序排列 { for(int i=0;i<t1-1;i++) { k=i; } } for(i=0;it2[k]) { k=j; } if(k!=i) { swap=t2[i]; t2[i]=t2[k]; t2[k]=swap; } } class Test2 extends Test { void sort(int t1,int t2[ ]) //重载超的方法 sort(),用选择法按升序排列 { for(int i=0;i<t1-1;i++) { k=i; for(i=0;i<t1-1;j++) { if(t2[j]<t2[k]) { k=j; } if(k!=i) { swap=t2[i]; t2[i]=t2[k]; t2[k]=swap; } } } } class SortTest extends java.awt.Applet } { public void paint(Graphics g) { int a[]={34,12,8,67,88,23,98,101,119,56}; //Test k=new Test(); 此句是非法的,不能创建实例对象。 Test1 k1=new Test1(); k1.sort(a.length,a); g.drawString("按降序排列的数据为",20,10); for(int i=0;i<10;i++) { g.drawString(""+a[i],20+i*30,30); } Test2 t2=new Test2(); t2.sort(a.lenght,a); g.drawString("按升序排列的数据为:",20,50); for(int i=0;i<10;i++) { g.drawString(""+a[i],20+i*30,70); } 程序运行的结果如下: 按降序排列的数据为: 119 101 98 67 56 34 23 12 8 按升序排列的数据为: 8 12 23 34 56 67 88 98 101 119 通过本例可以发现抽象的好处:从一个抽象可以派生出多个子,而且在各个子允 许对同一个抽象方法产生不同的方法体。 1.13.5 final final 有三个用途:其一,可以用于创建与常量一样的变量,其二,另外 2 个用途就是防止 被继承或方法被重载。 1. 最终 Java 引入了最终的概念,所谓最终既是那些不能再有子。说明最终时可以 在最前面加上修饰符 final。 例:final class A { //.... } class B extends A //错误!不能从 A 派生 { //....... } 注意:不能将一个抽象说明为 final ,因为抽象必须要被派生来实现它的抽象 方法。当一个被说明为 final 后,也相当于隐式的说明了它的所有方法为 final。 1.14 java 包,接口和异常 包是的容器,用于保证名空间的一致性。包以层次结构组织并可被明确地引入到一 个新定义。 接口是方法的显示说明,利用接口可以完成没有具体实现的。接口虽然与抽象相似, 但它具有多继承能力。一个可以有无数个接口,但是只能从一个父派生。 异常是代码运行时出现地非正常状态。Java 的异常是一个出现在代码描述异常状态的 对象。每当一个异常情况出现,系统就创建一个异常对象,并转入到引进异常的方法,方 法就根据不同的型捕捉异常。为防止由于异常而引起的退出,在方法退出前执行特定的 代码段。 1.14.1 包 1.14.1.1 package 语句 包是一种命名和可视控制的机制,用户可以把某些定义在一个包 ,也可以对定义在这个包施加访问权限,以限定包外或包 内的程序对其的某些进行访问。 定义包的格式: package pkg; Java文件系统将存储和管理这个包。例如:属于 pkg 包的.class 文件将存储到目录 pkg。注意:目录与包的名字完全一样。 package 语句可以创建包的层次结构,通过使用逗号,把每个包分开。 多级包层次结构的一般格式为: package pkg1[.pkg2[.pkg3]] 包层次结构必须反映 Java 开发系统的文件系统。比如:pacakge java.awt.Image; 1.14.1.2 import 语句 import 语句的功能是引入包或包。它们必须位于 package 语 句与这个文件或接口之间。 格式:import pkg1[.pkg2.(classname|*)] 这里,pkg1 是顶层包名,pkg2 是下一层包名,其间用点隔开。除了 对文件系统的限制外,对包的层次深度没有限制。最后以一个显示 方式指定一个名 classname 或*号,星号*指示 Java 编译器应该引入 整个包。 例子: import java.awt.Image; import java.lang.*; 1.14.2 接口 1.14.2.1 接口的概念 接口与存在着本质的差别,有它的成员变量和方法,而接口只有 常量和方法协议,从概念来讲,接口是一组方法协议和常量的集合。 接口在方法协议与方法体实体之间只起到一种称之为界面的作用,这 种界面限定了方法实体的参数型一定要与方法协议所规定的 参数型保持一致,除此以外,这种界面还限定了方法名、参数个数 及方法返回型的一致性。因此,在使用接口时,与接口之间并不 存在子与父的那种继承关系,在实现接口所规定的某些操作时只 存在的方法与接口之间保持一致的关系,而且一个可以和多个 接口之间保持这种关系,即一个可以实现多个接口。 1.14.2.2 接口的定义 格式: access interface name { return method-name(parameter-list); type final-varname=value; } 其,access 是访问修饰符。它只有 public 和未指定访问修饰符 两种情况。当未指定访问修饰符时,该接口只能为同一个包的 其他成员所用;当 public 修饰符说明时,该接口可以被其他任何 代码使用。name 是接口的名字,可以是任何有效的标识符。接 口体包括方法协议和常量,它们都用分号结束。在接口定义的 常量必须用变量名标识。他们隐式为 final 和 static,不能被实现 所改变。 例:interface Back { void c_back(int param); int SOON=4; } 该接口定义了一个方法协议,其参数为整数型;还定义了一整 数常量,其变量名为 SOON。该接口只能为同一个包其他成员 所用。 1.14.2.3 接口的实现 一旦接口被定义,就可以实现它。在的定义可以使用关键 字 implements 实现接口,然后在创建接口所定义的方法, implements 关键字的的格式: access class classname[extends superclass] [implements interfacename[,interface...]] { } ..... 例子:定义两个接口,其方法协议分别完成两个数的加法和减法 操作,然后分别实现这两个接口的方法。 import java.awt.Graphics; interface Demo_Add { public int add(int x,int y); } interface Demo_Sub { public int sub(int x,int y); } class Demo_Add_Sub implements Demo_Add, Demo_Sub { public int add(int x,int y) { return i+y; } public int sub(int x,int y) { return x-y; } } public class Add_Sub extends java.awt.Applet { public void paint(Graphics g) { Demo_Add_Sub k=new Demo_Add_Sub(); g.drawString("x+y="+k.add(30,10),30,30); g.drawString("x-y=" + k.sub(30,10),30,50); } } 程序运行结果如下: x+y=40; x-y=20; 1.14.2.4 接口的继承 一个接口可以继承其他接口,这可通过关键字 extends 来实现,其语 法与的继承相同。当一个实现一个派生接口时,必须实现所有 接口及其派生接口所定义的全部方法协议。 例:定义 5 个接口,其两个超接口。 import java.awt.Graphics; //定义接口 Test_C interface Test_C { public int add(int x,int y); } interface Test_B extends Test_C { public int sub(int x,int y); } interface Test_A extends Test_B { public int mul(int x,int y); } //定义接口 Test_Y interface Test_Y { public int div (int x,int y); } interface Test_X extends Test_Y { public int mod (int x,int y); } //定义 Test class Test implements Test_A ,Test_X { public int add(int x,int y) { return x+y; } public int sub(int x,int y) { } return x-y; } public int mul(int x,int y) { return x*y; } public int div (int x,int y) { return x/y; } public int mod (int x,int y) { return x%y; } public class Add_Mod extends java.awt.Applet { public void paint(Graphics g) { Test k =new Test(); g.drawString("x+y="+k.add(66,10),30,10); g.drawString("x-y="+k.sub(66,10),30,10); g.drawString("x*y="+k.mul(66,10),30,10); g.drawString("x/y="+k.div(66,10),30,10); g.drawString("x%y="+k.mod(66,10),30,10); } } 程序运行结果如下; x+y=76 x-y=56 x*y=660 x/y=6 x%y=6 注意:在实现一个接口时,任何都必须实现该接口或接口树的所有方法。 1.14.3 异常处理 所谓异常就是代码在运行时发生的非正常状态。Java 的异常是一个出现在代码描 述异常状态的对象。每当出现一个异常情况,就创建一个异常对象,并向导致错误 的方法抛出该对象。该方法捕捉到异常对象之后,可以选择用来处理该异常或不 管它。异常通常由 Java 运行系统产生,或者由用户的程序代码产生。Java 抛出的异 常大多是用户违背了 Java 语言的基本规则,或者超出了 Java 执行环境的约束。 1.14.4 异常处理机制 Java 通过 5 个关键字 try、catch、throw、throws 和 finally 管理异常处理。 try 用来监视它所在的那个程序块是否发生异常,如果发生异常就抛出它。对于系统 产生的异常或程序块未用 try 监视所产生的异常,将一律被 Java 运行系统自动抛 出。 catch 用来捕捉 try 程序所抛出的异常,将一律被 Java 运行系统自动抛出。 throw 可以用以人工地抛出一个异常 throws 用于从一个方法抛出一个异常。 finally 用于调用缺省异常处理。 下面是异常处理地一般形式: try { //有可能会出地代码块,被 try 监视。 } catch(ExceptionType1 ex) { //关于 ExceptionType1 的异常处理 } catch(ExceptionType2 ex) { //关于 ExceptionType2 的异常处理 } //...... finally { //在 try 块结束前被执行的代码块。 } 1.2 常用 System 全称:java.lang.System 扩展:Object 描述:公有最终。此与 Runtime 一起可以访问许多有用的系统功能。有一些方法在 两个都出现。exit()、gc()、load()和 loadLibrary()可以通过调用 Runtime 的同名方 法来响。特别有用的是变量 err、in 和 out,它们可以访问基本控制台 I/O。System 完全由域组成,这些域可以通过"System.变量名"和"System.方法()"的方法 进行访问。此不能被实例化。 实例变量: public static PrintStream err; public static InputStream in; public static PrintStream out; 每个变量对整个程序而言都是唯一的对象变量。这些对象可以访问系统的输入、输出和 错误输出。 常用方法: void exit(int status) 导致 Java 程序退出,向系统传递指定的状态代码。 void gc() 请求立即激活垃圾收集器开始清除不再使用的对象。 String getProperty(String key) String getProperty(String key,String def) 在系统属性表查找的一个属性。如果未发现属性,而且在 getProperty()方法指定了 参数 def,那么返回 def。 SwingUtil.ities 全称:javax.swing.SwingUtilities 扩展:Object 描述:公用。此包含了一组在 Swing 工具包使用的帮助器方法 常用方法: void paintComponent(Graphics g,Component c,Container p,int x,int y,int w,int h); void paintComponent(Graphics g,Component c,Container p,Rectangle r); void invokeLate(Runnable doRun); boolean isEventDispatchThread(); Component getRoot(Component c); JRootPane getRootPane(Component c);
JAVA相关基础知识 1、面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承: 继承是一种联结的层次模型,并且允许和鼓励的重用,它提供了一种明确表述共性的方法。对象的一个新可以从现有的派生,这个过程称为继承。新继承了原始的特性,新称为原始的派生(子),而原始称为新的基(父)。派生可以从它的基那里继承方法和实例变量,并且可以修改或增加新的方法使之更适合特殊的需要。 3.封装: 封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 4. 多态性: 多态性是指允许不同的对象对同一消息作出响。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了用程序函数同名问题。 2、String是最基本的数据型吗? 基本数据型包括byte、int、char、long、float、double、boolean和short。 java.lang.String是final型的,因此不可以继承这个、不能修改这个。为了提高效率节省空间,我们应该用StringBuffer 3、int 和 Integer 有什么区别 Java 提供两种不同的型:引用型和原始型(或内置型)。Int是java的原始数据型,Integer是java为int提供的封装Java为每个原始型提供了封装。 原始型封装 booleanBoolean charCharacter byteByte shortShort intInteger longLong floatFloat doubleDouble 引用型和原始型的行为完全不同,并且它们具有不同的语义。引用型和原始型具有不同的特征和用法,它们包括:大小和速度问题,这种型以哪种型的数据结构存储,当引用型和原始型用作某个的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始型实例变量的缺省值与它们的型有关。 4、String 和StringBuffer的区别 JAVA平台提供了两个:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String提供了数值不可改变的字符串。而这个StringBuffer提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用StringBuffers来动态构造字符数据。 5、运行时异常与一般异常有何异同? 异常表示程序运行过程可能出现的非正常状态,运行时异常表示虚拟机的通常操作可能遇到的异常,是一种常见运行错误java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。 6、说出Servlet的生命周期,并说出Servlet和CGI的区别。 Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。 与cgi的区别在于servlet处于服务器进程,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。 7、说出ArrayList,Vector, LinkedList的存储性能和特性 ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。 8、EJB是基于哪些技术实现的?并说出SessionBean和EntityBean的区别,StatefulBean和StatelessBean的区别。 EJB包括Session Bean、Entity Bean、Message Driven Bea

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值