回顾小结

Java中有俩种数据类型,其中主要有8中基本数据类型和引用数据类型,除了8中基本数据类型以外都是引用数据类型,8中基本数据类型分别是byte,short,int,long,char,boolean,float,double,具体如下: 1、boolean:数据值只有true或false,适用于逻辑计算。 2、char:char型(字符型)数据在内存中占用2个字节。char型数据用来表示通常意义上的字符,每个字符占2个字节,Java字符采用Unicode编码,它的前128字节编码与ASCII兼容字符的存储范围在\u0000~\uFFFF,在定义字符型的数据时候要注意加' ',比如 '1'表示字符'1'而不是数值1,3、byte:byte型(字节型)数据在内存中占用1个字节,表示的存储数据范围为:-128~127。 4、short:short型(短整型)数据在内存中占用2个字节。 5、int:int型(整型)数据在内存中占用4个字节。 6、long:long型(长整型)数据在内存中占用8个字节。 7、float:float型(单精度浮点型)数据在内存中占用4个字节。(float精度为7-8位) 8、double:double型(双精度浮点型)数据在内存中占用8个字节。 下面说说java中引用数据类型: 引用数据类型分3种:类,接口,数组; 一、类Class引用可以是我们创建的,这里我不多讲,主要是讲解几个java库中的类Object :Object是一个很重要的类,Object是类层次结构的根类,每个类都使用Object作为超类,所有对象(包括数组)都实现这个类的方法。用Object可以定义所有的类如: Object object= new Integer(1); 来定义一个Interger类Integer i=(Integer) object; 在来把这个Object强制转换成Interger类String :String类代表字符串,Java 程序中的所有字符串字面值(如"abc")都作为此类的实例来实现。检查序列的单个字符、比较字符串、搜索字符串、提取子字符串、创建字符串副本、在该副本中、所有的字符都被转换为大写或小写形式。Date :Date表示特定的瞬间,精确到毫秒。Date的类一般现在都被Calendar 和GregorianCalendar所有代替Void :Void 类是一个不可实例化的占位符类,它保持一个对代表 Java 关键字 void 的 Class 对象的引用。同时也有对应的Class如:IntegerLongBooleanByteCharacterDoubleFloatShort二、接口interface引用可以是我们创建的,这里我不多讲,主要是讲解几个java库中的接口interface List:列表 ,此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引 (在列表中的位置)访问元素,并搜索列表中的元素。List 接口提供了两种搜索指定对象的方法。从性能的观点来看,应该小心使用这些方法。在很多实现中,它们将执行高开销的线性搜索。 List 接口提供了两种在列表的任意位置高效插入和移除多个元素的方法。add() : 在列表的插入指定元素。remove():移除列表中指定位置的元素。get(int index):返回列表中指定位置的元素。 Map:K - 此映射所维护的键的类型V - 映射值的类型 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。put(K key,V value):将指定的值与此映射中的指定键关联(可选操作)。如果此映射以前包含一个该键的映射关系,则用指定值替换旧值(当且仅当,返回 true 时,才能说映射 m 包含键 k 的映射关系)。remove(Object key)如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。更确切地讲,如果此 映射包含从满足(key==null ? k==null :key.equals(k))的键 k 到值 v 的映射关系,则移除该映射关系。(该映射最多只能包含一个这样的映射关系.) get(Object key):返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。 这里我们主要是用String List Map Object 是最常用Number ArrayList Arrays等三、数组引用 数组:存储在一个连续的内存块中的相同数据类型(引用数据类型)的元 素集合。


数组中的每一个数据称之为数组元素,数组中的元素以索引来表示其存放的位置,索引(下标)从0开始。

数组的定义

第一种方式:类型[] 数组名; 如 int[] nums;
第二种方式:类型数组名[]; 如 int nums[];
大多数Java程序员喜欢使用第一种风格,因为它把数据类型int[],和变量名num分开了.
数组的初始化
Java中数组必先初始化后才能使用.
初始化就是给数组元素分配内存,并为每个元素赋初始值。
初始化数组的两种方式:
- 静态初始化:
语法格式:类型[] 数组名 = new 数组类型[]{元素1,元素2,元素3,...元素n};
简化语法:类型[] 数组名 = {元素1,元素2,元素3...元素n};
- 动态初始化:
如果我们事先不知道数组里存储哪些数据,只知道需要存储数据的个数,此时可以使用动态初始化方式。
动态初始化:初始化时由我们指定数组的长度,系统自动为数组元素分配初始值。
格式:类型[] 数组名 = new 数组类型[数组长度];
注意:无论,以哪种方式初始化数组,一旦初始化完成,数组的长度就固定了,不能改变,除非重新初始化。也就是说数组是定长的。
为什么Java里有基本数据类型和引用数据类型?
引用类型在堆里,基本类型在栈里。

栈空间小且连续,往往会被放在缓存。引用类型cache miss率高且要多一次解引用。

对象还要再多储存一个对象头,对基本数据类型来说空间浪费率太高
3种引用类型
类class ,就是自己定义的数据结构,还有一些java类库中的:包括string,date接口interface数组array
java中,数组的使用,会经过声明,分配空间,赋值三步,熟练的同学可以根据这三步骤直接一步到位
* 可以使用s.next()输入一个不含空格的字符串,
* s.nextInt():输入一个整数
* s.nextDouble():输入一个double
【回顾小结】* s.nextByte():输入一个字符
使用Scanner类:

(1)使用java.util包。import java.util.*;

(2)构造Scanner类对象,它附属于标准输入流System.in。Scanner s = new Scanner(System.in);

(3)常用的next()方法系列:nextInt():输入整数nextLine():输入字符串nextDouble():输入双精度数next():输入字符串(以空格作为分隔符)。
)readLine方法:读取一个文本行。通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行。 返回:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null。

System.out.println(); 是最常用的输出语句,它会把括号里的内容转换成字符串输出到输出窗口(控制台),并且换行,当输出的是一个基本数据类型时,会自动转换成字符串,如果输出的是一个对象,会自动调用对象的toString(); 方法,将返回值输出到控制台
System.out.print(); 与第一个很相似,区别就是上一个输出后会换行,而这个命令输出后并不换行。
System.out.printf(); 这个方法延续了C语言的输出方式,通过格式化文本和参数列表输出。

在JAVA中,驼峰规则一般是标识符用来命名变量、方法,主要是对多单词的标识符——第一个单词首字母为小写,其他单词首字母为大写。我们举几个例子就明白了:

father()//第一个单词的首字母小写

fatherMother()//第一个单词首字母小写,第二个单词首字母大写

fatherMotherChild() //第一个单词首字母小写,其他字母首字母大写



另外的,在JAVA中,使用标识符有几个规则要注意一下:

标识符要用字母、下划线“_”或者美元符号“$”作为开头,千万不能用数字作为开头
(这里有必要深究一下,假设用数字做标识符开头,像2E7即可以表示标识符也可以表示常量2*10^7,这样显然就带来了歧义,为了方便,就直接抹杀数字开头做标识符的方式)

标识符对大小写敏感,但不限制长度

标识符不可以是JAVA的关键字

特别的,JAVA不采用通常语言使用的ASCII字符集,而是采用国际通用的Unicode这样标准的国际字符集,所以,标识符也可以使用汉字,但一般不提倡用汉字命令。
.、所有变量。方法、类名:见名知意

2、类成员变量:首字母小写和驼峰原则

3、局部变量:首字母小写和驼峰原则

4、常量:大写字母和下划线:MAX_VLUE

5、类名:首字母大写和驼峰原则:Man,GoodMan

6、方法名:首字母小写和驼峰原则

总结:所有变量、方法的命名一般都遵循首字母小写和驼峰原则,例外的是常量要求全部大写并且单词间隔加下划线“_”,类名首字母大写。这样的话其实很好记,一般为主,例外为辅。】方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵从 驼峰形式。

正例: localValue / getHttpMessage() / inputUserId
、项目名全部小写
2、包名全部小写
在新建一个包项目时可能会涉及到多层设计,每层的包名要遵循包名全部小写的规范,如图在一个功能的逐层上级的包名全部是小写和字符组成





3、类名的命名要遵循首字母大写原则,类的名字必须由大写字母开头而单词中的其他字母均为小写;如果一个类名称是由多个单词组成,则每个单词的首字母均应为大写例如ModelWhAction;如果类名称中包含单词缩写,则这个所写词的每个字母均应大写,如:XMLExample,还有一点命名技巧就是由于类是设计用来代表对象的,所以在命名类时应尽量选择名词。


4、变量的命名要遵循通俗易懂的原则,比如名字就用 name ,而不是用a、b、c这样的命名。变量命名除了变量名外,实例,包括类、类常量,均采用大小写混合的方式,第一个单词的首字母小写,其后单词的首字母大写。变量名不应以下划线或美元符号开头,尽管这在语法上是允许的。但是在工作中这样做会降低代码的可阅读性,在工作上这是不规范的。
5、方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头。
6、需要用到的变量命名和方法命名要遵循首字母小写原则,如果名称是由多个单词组成,每个单词的首字母都要大写(除首个单词)。
如:public void toString(){}



7、使用驼峰命名法命名多个单词组成的变量名。
如:modelFacade

8、常量命名时需要遵循名称全部大写的原则。
如:public staticfinal long BSDY_SHZT_SHZ = 2; // 审核中

9、所有命名规则必须遵循以下规则:
1)、名称只能由字母、数字、下划线、$符号组成

2)、命名时不能以数字开头

3)、在命名是绝对不能出现Java关键字。

4)、绝对不允许在命名时出现中文及拼音命名。

【强制】常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。、包名:包名一般是小写英文字母

2、类名:单词首字母大写

java关键字一律小写。
3、变量名:

1) 标识符由字母、数字、下划线“_”、美元符号“$”或者人民币符号“¥”组成,并且首字母不能是数字。
2) 不能把关键字和保留字作为标识符。
3) 标识符没有长度限制。
4) 标识符对大小写敏感。

4、方法名:首单词小写,后面单词首字母大写

注意一下,不同变量类型默认的字节存储。Java中小数默认是double类型,例如上面(float)4.5,如果你直接写4.5,会在4.5这个地方出红色波浪线,表示这个地方有错误





a) 例如 a=3; b=a++; 那么a=4,b=3式子可以拆分为:b=a; a=a+1

b) 例如:a=3; b=++a; 那么:a=4,b=4; 式子可以拆分为:a=a+1; b=a。



变量的作用域指 可以使用此变量的简单名称来引用它的 程序区域。
变量声明 在程序中的位置 决定了变量的作用域。
按作用域来分,变量可以有下面4种:局部变量、成员变量、方法参数和异常处理参数。
局部变量在方法或方法的一块代码中声明,它的作用域为它所在的代码块(代码块是整个方法或方法中的某块代码,即以{厎包括的代码)。
成员变量是一个类的成员。它在一个类的内部,但在任何方法或构造器之外声明。成员变量的作用域是整个类。class Test1{
int age=10; //成员变量
public Outer(){
int age=20;
System.out.println(this.age); //这里输出的是成员变量10
System.out.println(age); //这里输出的是局部变量20
}

}
方法参数被传递给方法或构造器,它的作用域就是它所在方法或构造器的代码。
异常处理参数被传递给异常处理代码,它的作用域是异常处理部分,也就是catch语句后面的{厎之间的代码块。
在一个确定的域中,变量名应该是惟一的。通常,一个域用大括号{}来划定。

成员变量:(1)定义在类里,方法之外的变量。

(2)成员变量可以不显式初始化,它们可以由系统设定默认值;

(3)成员变量在所在类被实例化后,存在堆内存中

局部变量:(1)定义在方法体内部的变量。

(2)局部变量没有默认值,所以必须设定初始赋值。

(3)局部变量在所在方法调用时,存在栈内存空间中。

成员变量就是在类中定义的变量



局部变量可分为:

形参(形式参数)

在整个方法内有效

方法局部变量 (方法内定义)

从定义这个变量开始到方法结束这一段时间内有效

代码块局部变量 (代码块内定义)

从定义这个变量开始到代码块结束这一段时间内有效



Java存在块级作用域,在程序中任意大括号包装的代码中定义的变量,它的生命仅仅存在于程序运行该代码块时。

例如:for循环、while循环、方法或方法的参数列表里。在循环里声明的变量只要跳出循环,这个变量便不能再使用。同样,方法或方法的参数列表里定义的局部变量,当跳出方法体之外,该变量也不能使用了。

public class LocalVar {

public static void main(String[] args) { // main方法参数列表定义的局部变量args
int sum = 0; // main方法体内定义的局部变量sum
for(int i = 1; i < 5; i++) // for循环体内定义的局部变量i
sum += i;
System.out.println(sum);
}
}


成员变量(实例变量)局部变量(本地变量)类变量(静态属性,全局变量)
定义位置的区别:
1. 成员变量是定义在类里面的,是类中的属性
2. 局部变量是定义在方法里面的普通变量以及方法的形参
3.类变量:属于类的,被static修饰的属性

作用上的区别:
1. 成员变量是用来描述一类事物的公共属性
2. 局部变量是给函数提供一个用来保存数据的变量内存空间,形参:在方法体中任何位置都可访问;方法中定义的变量: 从定义处开始,直到所在代码块的结束
初始值的区别:
1. 成员变量的初始值是在创建对象的时候才有的,如果创建时没有赋初值,那么所
用的成员变量都是0值
2. 局部变量在创建的时候,是没有确定值,只能通过赋值操作给予一个确定的数据
,在Java中不能使用未赋值局部变量

[生存周期]
在代码中 一个变量或者一个对象从创建开始,到销毁结束,这就是他的生存周期

生存周期的区别:
1. 成员变量的生存周期是随对象创建而生,随着对象的销毁而不复存在【内存的堆
区】
2. 局部变量是在声明变量而生,在函数结束或者代码块结束,销毁【内存的栈区】
3.从类被加载时,类变量就分配内存空间,直到JVM退出被销毁

静态变量(static 所修饰的变量),是在程序运行之前,也就是编译阶段,分配内存。

void test(){
this.a = 1;
}
而this关键字的意思是,当前对象的a,也就是说,必须要有对象才能用this。

而对象的产生,必须在程序运行时,通过new产生。

所以静态变量不能使用this关键字。


方法的修饰符有两类:
1.访问控制修饰符(public,private,protected,package)
2.方法本身修饰符(static,final,abstract,native,synchronized)

类的修饰符:
1.前缀修饰符(public,abstract,final)
2.后缀修饰符(extends,implements)


访问控制符
(1)出现在成员变量与成员方法之前的访问控制符:private、public、default和protected
private:只能在类的内部访问。
public:在所有类中都可以访问。
default:只有同一个包中的类才能访问。
protected:不仅同一个包中的类可以访问,并且位于其他包中的子类也可以访问。


(2)出现在类之前的访问控制符:public、default
public:在所有类中可以访问。
default:在同一包中的类可以访问。


(3)default是Java中默认的控制字符。



static
static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。
被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。
只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。



final
final的作用随着所修饰的类型而不同。
1、final修饰类中的属性或者变量
无论属性是基本类型还是引用类型,final所起的作用都是变量里面存放的“值”不能变。这个值,对于基本类型来说,变量里面放的就是实实在在的值,如1,“abc”等。
而引用类型变量里面放的是个地址,所以用final修饰引用类型变量指的是它里面的地址不能变,并不是说这个地址所指向的对象或数组的内容不可以变,这个一定要注意。例如:类中有一个属性是final Person p=new Person("name"); 那么你不能对p进行重新赋值,但是可以改变p里面属性的值,p.setName('newName');
final修饰属性,声明变量时可以不赋值,而且一旦赋值就不能被修改了。对final属性可以在三个地方赋值:声明时、初始化块中、构造方法中。总之一定要赋值。


2、final修饰类中的方法
作用:可以被继承,但继承后不能被重写。

3、final修饰类
作用:类不可以被继承。





abstract
abstract(抽象)修饰符,可以修饰类和方法


1,abstract修饰类,会使这个类成为一个抽象类,这个类将不能生成对象实例,但可以做为对象变量声明的类型,也就是编译时类型,抽象类就像当于一类的半成品,需要子类继承并覆盖其中的抽象方法。


2,abstract修饰方法,会使这个方法变成抽象方法,也就是只有声明(定义)而没有实现,实现部分以";"代替。需要子类继承实现(覆盖)。


注意:有抽象方法的类一定是抽象类。但是抽象类中不一定都是抽象方法,也可以全是具体方法。


abstract修饰符在修饰类时必须放在类名前。


abstract修饰方法就是要求其子类覆盖(实现)这个方法。调用时可以以多态方式调用子类覆盖(实现)后的方法,也就是说抽象方法必须在其子类中实现,除非子类本身也是抽象类。


注意:父类是抽象类,其中有抽象方法,那么子类继承父类,并把父类中的所有抽象方法都实现(覆盖)了,子类才有创建对象的实例的能力,否则子类也必须是抽象类。抽象类中可以有构造方法,是子类在构造子类对象时需要调用的父类(抽象类)的构造方法。



面向对象思想就是不断的创建对象(属性与行为的封装,让二者作为整体参与程序执行),使用对象,指挥对象做事情。(在已有对象的情况下,直接使用对象,而不再去考虑对象的内部构造)



java是一种面向对象的程序设计语言,在程序中使用对象来描述具体的事物,当多个事物具有共同的特点时,可以将事物的共同特点进行抽象,然后封装成一个包含事物共同特点的集合,在java中叫做封装成一个类,可以将面向对象的主要特点是(抽象)封装、继承和多态。


Java 有几种基本数据类型? int 和 Integer 区别?
答:
a)byte,short,int,long,char,boolean,float,double
b)int 是基本数据类型,Integer 引用数据类型,Integer 是 int 的包装类,Integer 类提供了对数值的很多方法,int 的默认值 0,Integer 的默认值是 null。int 和 Integer 自动的装箱和拆箱装换。


解释什么是类的成员变量(类属性),局部变量,实例成员变量(普通属性)?
答:
a)定义在类的大括号内的变量都是成员变量。
b)在方法体中定义的变量和方法的参数语句块或者代码块中的变量被称为局部变量。
c)成员变量又分为实例成员变量和类成员变量(static 修饰)。

a)public:公有的,任何类都可以访问。
b)protected:受保护的,同一个包的类可以访问。不同包的子类可以访问。
c)友好的(默认):同一个包的类可以访问。
d)private:私有的,在同一个类中才能访问。

)try:保护代码,如果try中某行代码出现异常,则try中代码不再继续执行。
b)catch:捕获异常,当try中出现异常,则catch负责捕获异常,并处理。
c)throw:抛出异常。
d)throws:声明异常抛出。
e)finally:无论try中是否出现异常,finally一定执行。


)从 Java.lang.Thread 类派生一个新的线程类,重写它的 run() 方法。
b)实现 Runnable 接口,重写Runable接口中的 run() 方法。



构造方法能否被重写?为什么?
答:
不能,因为构造方法不能被继承,所以不能重写。

是否可以继承String类,为什么?
答:
因为 String 类是 final 类,final 修饰的类不能被继承。


其执行顺序也是1、2、3先后执行,这里需要注意的是:考虑继承特性。
子类与父类的执行顺序是:
1、先执行父类的静态代码块(父1)
2、子类的静态代码块(子1)
3、父类构造代码块(父2)
4、父类构造方法(父3)
5、子类构造代码块(子2)
6、子类构造方法(子3)
一般的类里面包含:
1、静态代码块(静态区、静态变量等)
2、构造代码块({ }中间的内容)
3、构造方法
.
静态代码块->父类构造方法->非静态代码块->本身构造方法
.
.
*/
.
1.顺序:静态代码块->父类构造方法->非静态代码块->本身构造方法。
2.非静态代码块每次构造对象实例时都执行,静态代码块只在加载类的时候执行一次。
当加载到一个静态属性的时候他的赋值对象为一个静态的对象,这个时候就会中断静态相关的加载,转而先去执行非静态相关的代码。这里还需要注意的是属性和代码块的加载遵循他们的先后出场顺序。

可以通过向上造型来验证,
A a = new B();
a.m(); // 这时执行的是A类中的静态方法。
无论如何类的加载都

①先进行解析(也就是声明静态变量但是不去初始化),也就是将静态变量放入方法区并且标记,标记一个值0。相当于只定义没有赋值。

②当所有的解析都过去的时候才进行初始化,初始化就是按照出场顺序来执行静态代码块和检查静态变量那里是否赋值值,如果有值得话那么就赋值,没有的话那么就将标记值赋值给静态变量。

注意:标记状态的值相当于无值它不可以直接参加运算但是可以间接的使用标记的值。类名调用。
静态变量是要占用内存的,在编译时只要是定义为静态变量了,系统就会自动分配内存给他,而内部类是在宿主类编译完编译的,也就是说,必须有宿主类存在后才能有内部类,这也就和编译时就为静态变量分配内存产生了冲突,因为系统执行:运行宿主类->静态变量内存分配->内部类,而此时内部类的静态变量先于内部类生成,这显然是不可能的,所以不能定义静态变量!
package daily;

/**
* created by huyanshi on 2019/1/28
*/
public class ClassLoadOrder {

public static void main(String[] args) {
B b = new B();
}
}


class A {

private int i = aFunc();

static {
System.out.println("A-----static");
}

public intaFunc() {
System.out.println("A----- default");
return 1;
}

public A() {
System.out.println("A----- constructor");

}
}

class B extends A {

private static int i1 = staticFunc();

public B() {
System.out.println("B----- constructor");
}

static {
System.out.println("B----- static");

}

private int i = bFunc();


private static intstaticFunc(){
System.out.println("B----- static func");
return 111;
}


public int bFunc() {
System.out.println("B----- default");
return 2;
}
}


1.先执行Test类的静态代码块后执行Test类的main方法,说明要执行类的方法需要先加载这个类。
2.在创建ClassB的对象时,先去加载了父类ClassA。说明加载子类时如果没有加载父类,会先加载父类。
3.静态变量赋值和静态代码块都会在类加载的时候执行,执行顺序与静态变量和静态代码块出现的先后顺序一致。
4.如果在类的静态代码块执行之前创建该类的对象,则会先执行该类的构造代码块和构造方法。
5.构造代码块总是在构造函数之前执行。
6.创建子类对象,需要先初始化父类的对象。所以先执行父类的构造代码块和构造方法,再执行子类的构造代码块和构造方法。
如当用户点击按钮或选择菜单项目时,Swing组件会产生一个 ActionEvent。
1.新建一个组件(如JButton)。

2. 将该组件添加到相应的面板(如JPanel)。

3. 注册监听器以监听事件源产生的事件(如通过ActionListener来响应用户点击按钮)。

4. 定义处理事件的方法(如在ActionListener中的actionPerformed中定义相应方法)。
2.抽象方法可以不完全被子类利用但接口必须被子类实行完毕
3.抽象方法:在类中没有方法体的方法,就是抽象方法。
4.抽象类:含有抽象方法的类就叫抽象类。
5.
6.抽象类中的抽象方法必须被实现!如果一个子类没有实现父类中的抽象方法,则子类也成为了一个抽象类!
7.抽象类中的普通方法,可以不必实现。
8.1 用abstract关键字来修饰一个类时,这个类叫做抽象类;用abstract来修饰一个方法时,该方法叫做抽象方法。例如 :
9.abstract class Animal { //用abstract来定义一个Animal为抽象类
10.}
11.public abstract void enjoy(); //用abstract来定义一个抽象方法"enjoy"
12.2 含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写。
13.3 抽象类不能被实例化。
14.4 抽象方法只需声明,而不需实现某些功能。如:
15.public abstract void enjoy();
16.上面的这个抽象方法不需要实现功能,而一般的方法 :
17.public void enjoy() {
18.System.out.print("叫声"); //有必要实现某些功能
19.}
20.Java中取资源时,经常用到Class.getResource()和ClassLoader.getResource()
21.package testpackage; public class TestMain{public static void main(String[] args) {System.out.println(TestMain.class.getResource("")); System.out.println(TestMain.class.getResource("/")); }}

在project中,相对路径的根目录是project的根文件夹,在此就是repathtest文件夹了。创建文件的写法是:
1
2 File f = new File("src/com/lavasoft/res/a.txt");
File f = new File("doc/b.txt");
注意:路径不以“/”开头;
脱离了IDE环境,这个写法就是错误的,也并非每个IDE都如此。
2、通过CLASSPATH读取包内文件
读取包内文件,使用的路径一定是相对的classpath路径,比如a,位于包内,此时可以创建读取a的字节流:
1 InputStream in = ReadFile.class.getResourceAsStream("/com/lavasoft/res/a.txt");
有了字节流,就能读取到文件内容了。
注意:这里必须以“/”开头

/**
* Java读取相对路径的文件
*

*/
public class ReadFile {
public static void main(String[] args) {
readTextA_ByClassPath();
readTextA_ByProjectRelativePath();
readTextB_ByProjectRelativePath();
}

/**
* 通过工程相对路径读取(包内)文件,注意不以“/”开头
*/
public static void readTextA_ByProjectRelativePath() {
System.out.println("-----------------readTextA_ByProjectRelativePath---------------------");
File f = new File("src/com/lavasoft/res/a.txt");
String a = file2String(f, "GBK");
System.out.println(a);
}

/**
* 通过工程相对路径读取(包外)文件,注意不以“/”开头
*/
public static void readTextB_ByProjectRelativePath() {
System.out.println("-----------------readTextB_ByProjectRelativePath---------------------");
File f = new File("doc/b.txt");
String b = file2String(f, "GBK");
System.out.println(b);
}


/**
* 通过CLASSPATH读取包内文件,注意以“/”开头
*/
public static void readTextA_ByClassPath() {
System.out.println("-----------------readTextA_ByClassPath---------------------");
InputStream in = ReadFile.class.getResourceAsStream("/com/lavasoft/res/a.txt");
String a = stream2String(in, "GBK");
System.out.println(a);
}

/**
* 文件转换为字符串
*
* @param f文件
* @param charset 文件的字符集
* @return 文件内容
*/
public static String file2String(File f, String charset) {
String result = null;
try {
result = stream2String(new FileInputStream(f), charset);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return result;
}

/**
* 文件转换为字符串
*
* @param in字节流
* @param charset 文件的字符集
* @return 文件内容
*/
public static String stream2String(InputStream in, String charset) {
StringBuffer sb = new StringBuffer();
try {
Reader r = new InputStreamReader(in, charset);
int length = 0;
for (char[] c = new char[1024]; (length = r.read(c)) != -1; ) {
sb.append(c, 0, length);
}
r.close();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}
相对路径:相对于某个基准目录所推出目的文件或目录所在的路径,没有唯一性
* 在相对路径中,”. /” 代表当前目录,“../”代表上级目录
推荐使用相对于当前classpath的相对路径
ClassLoader类的getResource(String path),getResourceAsStream(String path)等方法,使用相对于当前项目的classpath的相对路径来查找资源,读取属性文件常用到的ResourceBundle类的getBundle(String path)也是如此。
通过ClassLoader类的getResource(String 相对路径)方法获得当前classpath的绝对路径后拼资源的相对路径获得绝对路径
如:getClass().getClassLoader().getResource(“.”).toString();
同理:如果4.txt位于com.mac.util包下,与Hello.class处于同一目录。
用绝对路径读就是这样:String f = Hello.class.getResource(“/com/mac/util/4.txt”).getPath();
用相对路径读就是这样:
String f = Hello.class.getResource(“4.txt”).getPath();
在project中,相对路径的根目录是project的根文件夹,
创建文件的写法是:
File f = new File("src/com/lavasoft/res/a.txt");
File f = new File(“./a.txt”);
如果想在src下创建目录:
File f = new File(“src/a.txt”);
注意:
路径不以“/”开头;

2、通过CLASSPATH读取包内文件_
读取包内文件,使用的路径一定是相对的classpath路径,
比如a.txt,位于包内,此时可以创建读取a的字节流:
InputStream in = ReadFile.class.getResourceAsStream("/com/lavasoft/res/a.txt");

注意:
这里必须以“/”开头;

*3 由于bin目录(包括web应用中WEB-INF下的classes目录)统称为classpath(类路径) 我们还可以采用下边两种方式来读取。
*
1. 通过字节码对象读取
假如当前类为:Hello.java,它所在的包是:com.mac.util
在Hello.java中:String f = Hello.class.getResource(“/4.txt”).getPath(); 这种以“/”开头的是以绝对路径方式读取,意思是从bin目录下开始读取4.txt,
” /=D:\eclipse\workspace\test\bin\。
this 指向当前实例对象的引用
采用abstract方法的类本来就是抽象类,并且必须声明为abstract。abstract类不能实例化。仅当abstract类的子类实现其超类的所有abstract方法时,才能实例化abstract类的子类。这种类称为具体类,以区别于abstract类。如果abstract类的子类没有实现其超类的所有abstract方法,该子类也是abstract类。abstract关键字不能应用于static、private或final方法,因为这些方法不能被重写,因此,不能在子类中实现。final类的方法都不能是abstract,因为final类不能有子类。abstract关键字可以修饰类或方法。abstract类可以扩展(增加子类),但不能直接实例化。abstract方法不在声明它的类中实现,但必须在某个子类中重写。
break语句通常在每个case块末尾使用,用于退出switch语句。
如果没有break语句,执行流将进入所有后面的case和/或default块。
catch
catch关键字用来在try-catch或try-catch-finally语句中定义异常处理块。
开始和结束标记{和}是catch子句语法的一部分,即使该子句只包含一个语句,也不能省略这两个标记。每个try块都必须至少有一个catch或finally子句。如果某个特定异常类未被任何catch子句处理,该异常将沿着调用栈递归地传播到下一个封闭try块。如果任何封闭try块都未捕获到异常,Java解释器将退出,并显示错误消息和堆栈跟踪信息。

finally关键字用来定义始终在try-catch-finally语句中执行的块。finally块通常包含清理代码,用在部分执行try块后恢复正常运行。
-示例-
try{
<可能引发异常的块>
}
catch(e){
<处理异常e的代码>
}
finally{
<有异常或无异常情况下都执行的语句>
}
-注释-
开始和结束标记{和}是finally子句语法的一部分,即使该子句只包含一个语句,也不能省略这两个标记。每个try块都必须至少有一个catch或finally子句。如果执行try块的任何部分,不论是否出现异常,也不论try或catch块是否包含return、continue或break语句,都一定会执行finally块中的代码。如果不出现异常,控件将跳过try块,进入finally块。如果在执行try块期间出现异常,并且相应的catch块包含break、continue或return语句,控件将首先穿过finally块,之后再执行break、continue或return。
instan

    推荐阅读