基本知识
一. Java基础
1. java语言的特点:
①简单:没有头文件、指针、运算符重载
②面向对象
③分布式:可以通过URL打开访问网络上的应用
④健壮性:Java消除有出错倾向的状态:指针
⑤安全:禁止运行时堆栈溢出...
⑥可移植性:JVM
⑦体系结构中立
⑧解释型
⑨高性能
⑩多线程
⑾动态性
2. jdk的三个版本:
① j2se-->JAVASE-->标准版 主要用于桌面应用程序
② j2me-->JAVAME-->微缩版 主要应用于嵌入式系统开发 如手机、PDA的编程
③ j2ee-->JAVAEE-->企业版 主要应用于分布式网络程序的开发,电子商务及ERP
3. JDK目录:
bin:java开发工具,是一些可执行程序
lib: Java的一些库文件,是java运行的基础
demo:java自带一些示例
4. 环境变量的配置:
JAVA_HOME:jdk安装路径
path:%JAVA_HOME%\bin
classpath:与我们import和include有关
%JAVA_HOME%\lib\tools.jar
%JAVA_HOME%\lib\dt.jar
.表示当前路径
5.java中常用命令
包的命名规范:
公司的域名倒写+项目名称+模块名称
带包编译:
javac -d ./ HelloWorld.java(其中的/可以省略)
带包运行:
java com.ambow.javabase.day1.HelloWorld(包的路径 注意运行时文件名首字母大写)
java中的注释类型:
//单行注释
/*... ...*/多行注释
/**... ...*/文档注释
javadoc -d ./docs HelloWorld.java
java中的压缩命令:
jar -cvf jar文件名 包路径(压缩包存放在当前路径)(c代表create)
java中的解压缩命令:
jar -xvf (包路径)jar包名(x代表extend)
运行jar包里面的程序:java -classpath (jar包名) (路径+类文件)
或java -cp (jar包名) (路径+类文件)
6.编写Java代码时要注意的一些小知识点
一个源文件中至多只能有一个public的class
源文件名必须和它定义的public的类名相同
一个文件中可以同时写多个类,但是只能有一个公开的类
Main方法是java程序的入口
7.类加载:
加载代码 (类加载器)
将class字节码文件读入内存,并放在数据的方法区,在堆区中创建java.lang.Class对象,用于封装类在方法区内的数据结构
连接
把已经读入内存的类的二进制数据合并到jvm运行环境中去
验证代码 (字节码校验器)
保证加载类有正确的内部结构,并与其他类协调一致辞主要有以下几个方面:文件结构检查,语义检查,字节码验证,二进制兼容的验证
准备
Jvm为类的静态变量分配内存,并调置默认的初始值
解析
Jvm把类的二进制数据中的符号引用替换为直接引用
执行代码 (解释器)
Jvm执行类初始化语句,为类静态变量赋以初值
8. 标识符、关键字、数据类型:
标识符命名规则:
1.只能是字母、_、$开头
2.允许名称中存在字母、_、$、数字
3.区分大小写
4.不能使用java中的关键字
5.长度不限
标识符命名规范:
1.见名知意
2.尽量避免使用_,$
3.类和接口的命名每个单词的首字母要大写
4.字段方法以及对象的首字母小写其他单词的首字母大写
5.常量全部大写
6.包名全部小写
9. 关键字列表:
abstract boolean break byte case catch char class continue default do double else extends enum(枚举) false final finally float for if implements import instanceof int interface long native new null package private protected public return short static super switch synchronized(线程同步) this throw throws transient true try void volatile(共享) while
Java 中 true false 不是关键字,而是boolean类型的字面量
保留字:const,goto
所有的关键字都是小写,friendly,sizeof不是java的关键字
10. 数据类型:
①基本数据类型
byte 8
short 16
int 32
float 32
long 64
double 64
char 16 unicode---一个字符占两个字节
boolean(布尔值)
float f = 0.1;编译错误,系统默认把小数当做double来看待,double是64位,float是32位,会造成精度丢失
直接表示一个float类型的值必须在数字后跟‘f’或‘F’
直接表示一个double类型的值必须在数字后跟‘d’或‘D’
②引用数据类型:数组、类、接口
③基本数据类型的转换顺序
byte--->short--->int--->long--->float--->double
char--->(char指向int)
在上图中,顺着箭头方向的类型转换可以自动进行,逆箭头方向的转换或无箭头类型之间的转换必须强制进行。
在图3-1中有6个实箭头,表示无数据丢失的转换;有3个虚箭头,表示可能有精度损失的转换
11. 转义字符:
转义字符 描述
\ddd 1到3位8进制数所表示的字符(ddd)
\uxxxx 1到4位16进制数所表示的字符(xxxx)
\’ 单引号字符
\’’ 双引号字符
\\ 反斜杠字符
\r 回车
\n 换行
\f 走纸换页
\t 横向跳格(一次跳8个字位)
\b 退格
12.String类的介绍:
①字符串String类型与其他类型数据相加为String
②在java.lang包下,可以直接使用
③String类的toString()、equals()、hashCode()已被重写
④被final修饰,不可以被继承
Object类:
==比较内存地址
equals与==效果相同
String类:
String s1 = "a";//在字符串池
String s2 = "a";
System.out.println(s1==s2);
String c = new String("a");//在堆中申请空间
String d = new String("a");
System.out.println(c==d);
StringBuffer 可将字符串缓冲区安全地用于多个线程,可以在必要时对这些方法进行同步
StringBuilder 一个可变的字符序列,此类提供一个与 StringBuffer 兼容的 API,但不保证同步。
⑤在JavaSE和Java EE环境下String s1 = "a";表示一个对象;String c = new String("a");表示两个对象,分别是字符串池中已有的“a”和对象new String("a");但在JavaME环境下,由于内存太小,String c = new String("a");也只有一个对象。
13.运算符
&&和&区别:
1.&&逻辑运算与,&位运算与
2.逻辑运算支持短路运算,位运算不支持
<< 左移 高位舍弃,低位补0
>> 右移 低位舍弃,高位补符号位(最高位)
>>> 无符号右移 低位舍弃,高位补0
%:求模(余数)
~ 取反
& 有0为0
| 有1为1
∧异或 一样的为0不一样的为1
求2的3次方最快的算法:2<<2
说明:
Java中,任何数据类型的数据(包括基本类型和引用类型)都可以通过==或!=来比较是否相等(这与C、C++不同)。
关系运算的结果返回true或false,而不是C、C++中的1或0。
等于和不等于适用于所有内建的数据类型,但其他比较不适用于boolean类型。
14.java语句
switch case 实现多分支选择结构的语句:
switch(expression) {
case 整数值1 : 语句; break;
case 整数值2 : 语句; break;
case 整数值3 : 语句; break;
case 整数值4 : 语句; break;
case 整数值5 : 语句; break;
//..
default:语句; }
1.表达式expression可以是以下几种基本数据类型和枚举
类型(byte,short,int,char,String,枚举)
2.case子句中的值必须是常量,而且所有case子句中的值应是不同的。
3.case通常与break语句联用,以保证多路分支的正确实现,多个case可以公用一组执行语句。
4.在switch case语句中,当碰到满足条件的case值,如果之后的语句没有break则一直执行,直到遇见break停止;default相当于else,包含在switch case语句中,如果default之前的case都不满足条件,则执行default;注意:如果case语句不满足条件,则程序将不会执行(进入)这条语句,也就不管这条语句有没有break了。
例如:int i = 1;
Switch(i){
case 0: System.out.println(“zero”);break;
case 1: System.out.println(“one”);
case 2: System.out.println(“two”);
default: System.out.println(“default”);
}
//输出结果为 one,two, default
for(初始值;条件表达式;增量){ }for语句中的3个表达式都可以置空(为零),当循环体内的语句为一条时,可以不加{ }
break :
不带标号的break语句,跳出它所在的循环语句或switch 语句,并从紧跟该循环语句或switch 语句后的第一条语句处执行
continue:
不带标号的continue语句,用来结束本次循环,跳过循环体中下面尚未执行的语句,接着进行终止条件的判断,以决定是否继续循环
带标号的continue语句跳转到标号指明的外层循环中。
15.数组
数组的缺点:
1.只能保存一种类型
2.长度必须指定
一维数组:(注意:数组当中的元素可以重复)
1.int[] a;
int a[];
2.a = new int[5];
int[] b = new int[5];//对
int[] c = {1,2,3,4};//对
int[] d = new int[5]{1,2,3,4,5};//错
int[] e = new int[]{1,2,3};//对
3.数组的起始位置是从0开始的
4.char[] a = new char[5];默认是0所对应的字符
boolean[] a = new boolean[5];false
User[] a = new User[5];null
int[] a = new int[5];0 如果不是数组则没有默认值
5.求数组长度:a.length
二维数组:数组的数组,即数组里面的元素还是数组,数组的长度为行数(行数确定列数,相反则不行)
①声明:
int[][] a = new int[2][3];//其中2、3分别表示两行、三列
②下列声明正确的是:
int[][] a = new int[][]{{1,2,3},{4,5,6}};//对 {1,2,3}和{4,5,6}分别对应两个数组,并代表两行 输出结果为:
123
456 两行
int[][] b = {{1,2},{3,4}};//对
int[][] c = new int[][3];//错
int[][] d = new int[2][];//对(编译成功)
int[][] e = new int[][3]{1,2,3,4,5,6};//错
int[][] f = new int[2][]{1,2,3,4,5,6};//错
int[][] g = new int[2][];//对
g[0] = new int[3];
g[1] = new int[5];
数组拷贝函数:
public static void arrayCopy(Object src,
int srcPos,
Object dest,
int destPos,
int length)
src:源数组
srcPos:从源数组中第几个位置开始
dest:目标数组
destPos:目标数组从第几个位置开始
length:拷贝多长
16.面向对象
面向对象的目的:
在计算机中来模拟现实世界对象可以被认为是一种变量,也就可以当成变量来使用
面向对象与面向过程:
1.过程:先有算法-->数据结构
2.对象:数据结构-->算法
17.类的方法
编写类的方法:先抽象再封装
抽象:提取出主要内容,忽略次要的,一类事物所具有的共性
封装:属性私有化提供公有的setter/getter方法,把一些实现细节不让用户看到
封装的好处:
1.数据更安全,增加了验证
2.可以不用去关注内部实现的细节,增加重用性
构造方法:
作用在创建对象的时候给属性进行初始化工作
特点:
1.无返回值
2.方法名与类名相同
3.在创建该类对象的时候被调用
4.如果本类不写任何构造函数,系统会默认提供一个无参构造,如果自定义构造函数,无参构造失效
调用方法:首先进行严格类型调用,然后向上就近原则,方法前如果有返回值,则一定要return相应类型的值,并且放在语句块最后执行,代表语句结束。
18.实例代码块和静态代码块
实例代码块:
在类中用{ }包含起来的部分,在创建实例的时候进行调用,先于构造方法被调用,创建几个实例调用几次
静态代码块:
static{ }在创建多个实例的时候只调用一次,但是静态代码块并不是依靠创建对象来进行调用的,而是在JVM在加载类的时候进行调用的
19.函数的重载和覆盖
函数(方法)的重载(overload):编译时多态,方法名相同,参数列表不同
函数(方法)的覆盖(override):运行时多态
1.方法名、参数列表、返回值全部一致
2.子类的访问修饰符要>=父类的访问修饰符
3.子类的返回值类型可以是父类返回值的子类型(jdk1.5)
4.抛出异常类型不能更宽泛
20.this和super关键字
this关键字:
1.区分属性间重名
2.this可以实现构造方法之间相互调用,但是一定要在第一行调用,只能单向调用
Super关键字:
子类的构造方法要先调用父类的构造方法,如果父类中没有无参构造,必须显式的去调用父类中有参构造,super(参数1,参数2,...),但是super语句必须放在第一行
21. 参数传递:
基本数据类型按值传递(拷贝值)
引用数据类型按引用传递(拷贝引用)
基本数据类型: int n = 10
copy值一份
引用数据类型:User user = new User();
class MyInt {
public int n = 10;
public static void change(MyInt n) {
n.n++;//在原对象空间中改变变量n的值
System.out.println(n.n);
// MyInt mm = new MyInt();/*在新对象空间(mm)中改变n的值
// 不影响原对象空间中n的值*/
//
// mm.n = 100;
// n = mm;
// System.out.println(mm.n);
}
}
22. 继承和多态:
①继承概念:使用已经存在的类的定义作为基础来创建新类的技术,新类可以增加新的属性和功能,不能选择性地继承父类
继承优点:代码复用,缩短开发周期,降低开发成本
继承的两种不同的编写方式:(private和Default不能被继承)
创建过程:汽车类->轿车类 特化
先有轿车、卡车-->汽车类 泛化
java中的继承只能是单继承
java中所有的类的父类是Object
②多态:指的是编译时类型变化,而运行时类型不变。
多态分两种:
编译时多态:编译时动态重载
运行时多态:指一个对象可以具有多个类型。
Animal d = new Dog();
编译时类型 运行时类型
注意:属性之间没有多态调用,子类增添父类没有的方法不属于多态
一个对象可以引用多种实际类型的现象叫做多态,在运行时能够自动选择调用适当的方法的现象称为动态绑定
23.final关键字
final修饰的类不可以被继承:例如String
final修饰的方法不可以覆盖,但是可以被继承
修饰变量:该变量的值不能被改变(常量)
24. static关键字:访问修饰符
--在类加载的时候static进行初始化
1.创建子类对象的时候
2.访问类中的静态成员的时候
3.声明一个类类型的时候Test t1不加载类
4.new的时候会加载
静态变量:
一个类只有一份,被所有实例共享(值累加,会变动)
静态方法:
静态方法只可以访问静态成员,可以覆盖静态方法
非静态方法可以访问静态成员、非静态成员,不可以覆盖静态方法
静态方法不需要创建对象就能够被调用,通过类名就可以调用(类名.方法名())
静态代码块:static{}
25. 单例模式:
全世界只有此类的一个对象
第一种 懒汉式(多线程的时候不安全,不能保证对象唯一)
public class Singleton2 {
//懒汉式
private static Singleton2 singleton2;
private Singleton2(){
}
public static Singleton2 getInstance() {
if(singleton2==null){
singleton2 = new Singleton2();
return singleton2;
}else {
return singleton2;
}
}
}
第二种 恶汉式(浪费资源)
public class Singleton {
//恶汉式
private static Singleton singleton = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return singleton;
}
}
26.抽象类(abstract)
1.放在访问修饰符后面,修饰方法,那么方法所在类也必须被abstract修饰变为抽象类,被abstract修饰的方法变为抽象方法(没有方法体)
2.抽象类中可以没有抽象方法
3.抽象类的作用:制定一些规范,要求子类去实现(遵守)
4.抽象类注意事项:
①抽象类不能被实例化,但可以声明对象(变量),而且必须为空null
②可以定义一个抽象类的引用 Person p = new Student();//Person是抽象类,Student是继承了Person类的子类
27.接口(interface)
1.一个特殊的抽象类
2.接口可以多继承
3.接口中的方法为抽象方法,而且是public abstract,可以缺省(不能是static,因为非静态方法不可以覆盖静态方法)
4.一个类可以实现多个接口,必须要把所有接口中所有抽象方法实现
5.接口中出现的属性 public static final
6.接口的作用:解决多继承的问题
28.修饰符的修饰范围
Modifiers InsideClass TheSamePackage Subclass other
public Yes Yes Yes Yes
protected Yes Yes Yes No
Default(friendly) Yes Yes No No
private Yes No No No
29.包装类
包装类与基本数据类型的区别:
1.包装类对基本数据类型进行了一些扩展,定义了许多类型之间转换的方法
2.针对一些集合类型他要求我们放进去的是Object,基本数据类型不能满足,就只能使用包装类对象
包装类(也叫封装类)如:
Integer
Long
Float
Double
叫它包装是因为你在声明时只需如:
int a=2;
long b=4;
float c=3.4f;
double d=6.32;
而不需要用到包装类,如:
Integer a=new Integer(2);
Long b=new Long(4);
Float c=new Float(3.4f);
Double d=new Double(6.32);
就是说包装类把一些原始的东西都包装起来,我们用的时候就不需要直接使用它们,这样可以简化代码工作
30.异常
异常与错误:
①异常是在一个程序执行过程中出现的一个事件,它中断了正常指令运行
②错误是偏离了可接受的代码行为的一个动作或一个实例
异常的结构及分类:
Throwable
Error Exception
运行时异常(未检查异常) 编译时异常(已检查异常)
捕获异常的方式:
try{}catch(Exception e){}
1.catch块可以有多个,但是参数要按从小到大的顺序写
getMessage()是Exception继承自Throwable的一个方法,作用是返回此throwable的详细消息字符串
printStackTrace()打印异常堆栈信息,它可以将异常产生的详细信息打印出来,方便查错改错
finally的用法:无论有没有异常或者是产生的异常有没有被捕获,它都会被执行
try{}catch(){}finally{}
try{}finally{}
catch{}finally{}//不可以这样搭配
try{}和finally{}都不能单独使用, try{}可以抛出异常。
throws 的作用是将当前方法中的异常抛出,交给调用者处理
throw 将捕获的异常抛出,好处是可以对异常做自定义的封装信息,让用户更能接受
在继承关系中,子类中覆盖的父类中的方法抛出的异常范围不能比父类中抛出异常范围更大
31.常见的几种异常:
java.lang.ArithmeticException 算术数学异常
int n=0;
System.out.println(10/n);//by zero
java.lang.NumberFormatException 数值格式转换异常
int data=Integer.parseInt("abcd");
java.lang.ClassCastException 类型转换异常
Object obj=new Object();
Exception e=(Exception)obj;
java.lang.NullPointerException 空指针异常
java.lang.ArrayIndexoutofBoundsException 数组下标越界异常
java.lang.SecurityException 安全异常
算术异常类:ArithmeticExecption
空指针异常类:NullPointerException
类型强制转换异常:ClassCastException
数组负下标异常:NegativeArrayException
数组下标越界异常:ArrayIndexOutOfBoundsException
违背安全原则异常:SecturityException
文件已结束异常:EOFException
文件未找到异常:FileNotFoundException
字符串转换为数字异常:NumberFormatException
操作数据库异常:SQLException
输入输出异常:IOException
方法未找到异常:NoSuchMethodException
java.lang.AbstractMethodError
抽象方法错误。当应用试图调用抽象方法时抛出。
java.lang.AssertionError
断言错。用来指示一个断言失败的情况。
java.lang.ClassCircularityError
类循环依赖错误。在初始化一个类时,若检测到类之间循环依赖则抛出该异常。
java.lang.ClassFormatError
类格式错误。当Java虚拟机试图从一个文件中读取Java类,而检测到该文件的内容不符合类的有效格式时抛出。
java.lang.Error
错误。是所有错误的基类,用于标识严重的程序运行问题。这些问题通常描述一些不应被应用程序捕获的反常情况。
java.lang.ExceptionInInitializerError
初始化程序错误。当执行一个类的静态初始化程序的过程中,发生了异常时抛出。静态初始化程序是指直接包含于类中的static语句段。
java.lang.IllegalAccessError
违法访问错误。当一个应用试图访问、修改某个类的域(Field)或者调用其方法,但是又违反域或方法的可见性声明,则抛出该异常。
java.lang.IncompatibleClassChangeError
不兼容的类变化错误。当正在执行的方法所依赖的类定义发生了不兼容的改变时,抛出该异常。一般在修改了应用中的某些类的声明定义而没有对整个应用重新编译而直接运行的情况下,容易引发该错误。
java.lang.InstantiationError
实例化错误。当一个应用试图通过Java的new操作符构造一个抽象类或者接口时抛出该异常.
java.lang.InternalError
内部错误。用于指示Java虚拟机发生了内部错误。
java.lang.LinkageError
链接错误。该错误及其所有子类指示某个类依赖于另外一些类,在该类编译之后,被依赖的类改变了其类定义而没有重新编译所有的类,进而引发错误的情况。
java.lang.NoClassDefFoundError
未找到类定义错误。当Java虚拟机或者类装载器试图实例化某个类,而找不到该类的定义时抛出该错误。
java.lang.NoSuchFieldError
域不存在错误。当应用试图访问或者修改某类的某个域,而该类的定义中没有该域的定义时抛出该错误。
java.lang.NoSuchMethodError
方法不存在错误。当应用试图调用某类的某个方法,而该类的定义中没有该方法的定义时抛出该错误。
java.lang.OutOfMemoryError
内存不足错误。当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误。
java.lang.StackOverflowError
堆栈溢出错误。当一个应用递归调用的层次太深而导致堆栈溢出时抛出该错误。
java.lang.ThreadDeath
线程结束。当调用Thread类的stop方法时抛出该错误,用于指示线程结束。
java.lang.UnknownError
未知错误。用于指示Java虚拟机发生了未知严重错误的情况。
java.lang.UnsatisfiedLinkError
未满足的链接错误。当Java虚拟机未找到某个类的声明为native方法的本机语言定义时抛出。
java.lang.UnsupportedClassVersionError
不支持的类版本错误。当Java虚拟机试图从读取某个类文件,但是发现该文件的主、次版本号不被当前Java虚拟机支持的时候,抛出该错误。
java.lang.VerifyError
验证错误。当验证器检测到某个类文件中存在内部不兼容或者安全问题时抛出该错误。
java.lang.VirtualMachineError
虚拟机错误。用于指示虚拟机被破坏或者继续执行操作所需的资源不足的情况。
java.lang.ArithmeticException
算术条件异常。譬如:整数除零等。
java.lang.ArrayIndexOutOfBoundsException
数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
java.lang.ArrayStoreException
数组存储异常。当向数组中存放非数组声明类型对象时抛出。
java.lang.ClassCastException
类造型异常。假设有类A和B(A不是B的父类或子类),O是A的实例,那么当强制将O构造为类B的实例时抛出该异常。该异常经常被称为强制类型转换异常。
java.lang.ClassNotFoundException
找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
java.lang.CloneNotSupportedException
不支持克隆异常。当没有实现Cloneable接口或者不支持克隆方法时,调用其clone()方法则抛出该异常。
java.lang.EnumConstantNotPresentException
枚举常量不存在异常。当应用试图通过名称和枚举类型访问一个枚举对象,但该枚举对象并不包含常量时,抛出该异常。
java.lang.Exception
根异常。用以描述应用程序希望捕获的情况。
java.lang.IllegalAccessException
违法的访问异常。当应用试图通过反射方式创建某个类的实例、访问该类属性、调用该类方法,而当时又无法访问类的、属性的、方法的或构造方法的定义时抛出该异常。
java.lang.IllegalMonitorStateException
违法的监控状态异常。当某个线程试图等待一个自己并不拥有的对象(O)的监控器或者通知其他线程等待该对象(O)的监控器时,抛出该异常。
java.lang.IllegalStateException
违法的状态异常。当在Java环境和应用尚未处于某个方法的合法调用状态,而调用了该方法时,抛出该异常。
java.lang.IllegalThreadStateException
违法的线程状态异常。当县城尚未处于某个方法的合法调用状态,而调用了该方法时,抛出异常。
java.lang.IndexOutOfBoundsException
索引越界异常。当访问某个序列的索引值小于0或大于等于序列大小时,抛出该异常。
java.lang.InstantiationException
实例化异常。当试图通过newInstance()方法创建某个类的实例,而该类是一个抽象类或接口时,抛出该异常。
java.lang.InterruptedException
被中止异常。当某个线程处于长时间的等待、休眠或其他暂停状态,而此时其他的线程通过Thread的interrupt方法终止该线程时抛出该异常。
java.lang.NegativeArraySizeException
数组大小为负值异常。当使用负数大小值创建数组时抛出该异常。
java.lang.NoSuchFieldException
属性不存在异常。当访问某个类的不存在的属性时抛出该异常。
java.lang.NoSuchMethodException
方法不存在异常。当访问某个类的不存在的方法时抛出该异常。
java.lang.NullPointerException
空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。
java.lang.NumberFormatException
数字格式异常。当试图将一个String转换为指定的数字类型,而该字符串确不满足数字类型要求的格式时,抛出该异常。
java.lang.RuntimeException
运行时异常。是所有Java虚拟机正常操作期间可以被抛出的异常的父类。
java.lang.SecurityException
安全异常。由安全管理器抛出,用于指示违反安全情况的异常。
java.lang.StringIndexOutOfBoundsException
字符串索引越界异常。当使用索引值访问某个字符串中的字符,而该索引值小于0或大于等于序列大小时,抛出该异常。
java.lang.TypeNotPresentException
类型不存在异常。
32.二进制、八进制、十进制和十六进制
十六进制就是逢16进1
0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f 十六个字符组成
比如 1+f=10 (满16了,进1位)
计算机中常用的数的进制主要有:二进制、八进制、十六进制,学习计算机要对其有所了解。
2进制,用两个阿拉伯数字:0、1;
8进制,用八个阿拉伯数字:0、1、2、3、4、5、6、7;
10进制,用十个阿拉伯数字:0到9;
16进制就是逢16进1,但我们只有0~9这十个数字,所以我们用A,B,C,D,E,F这五个字母来分别表示10,11,12,13,14,15。
字母不区分大小写。
以下简介各种进制之间的转换方法:
一、二进制转换十进制
例:二进制 “1101100”
1101100 ←二进制数
6543210 ←排位方法
例如二进制换算十进制的算法:
1*26 + 1*25 + 0*24 + 1*23 + 1* 22 + 0*21 + 0*20
↑ ↑
说明:2代表进制,后面的数是次方(从右往左数,以0开始)
=64+32+0+8+4+0+0
=108
二、二进制换算八进制
例:二进制的“10110111011”
换八进制时,从右到左,三位一组,不够补0,即成了:
010 110 111 011
然后每组中的3个数分别对应4、2、1的状态,然后将状态为1的相加,如:
010 = 2
110 = 4+2 = 6
111 = 4+2+1 = 7
011 = 2+1 = 3
结果为:2673
三、二进制转换十六进制
十六进制换二进制的方法也类似,只要每组4位,分别对应8、4、2、1就行了,如分解为:
0101 1011 1011
运算为:
0101 = 4+1 = 5
1011 = 8+2+1 = 11(由于10为A,所以11即B)
1011 = 8+2+1 = 11(由于10为A,所以11即B)
结果为:5BB
四、二进制数转换为十进制数
二进制数第0位的权值是2的0次方,第1位的权值是2的1次方……
所以,设有一个二进制数:0110 0100,转换为10进制为:
计算: 0 * 20 + 0 * 21 + 1 * 22 + 1 * 23 + 0 * 24 + 1 * 25 + 1 * 26 + 0 * 27 = 100
五、八进制数转换为十进制数
八进制就是逢8进1。
八进制数采用 0~7这八数来表达一个数。
八进制数第0位的权值为8的0次方,第1位权值为8的1次方,第2位权值为8的2次方……
所以,设有一个八进制数:1507,转换为十进制为:
计算: 7 * 80 + 0 * 81 + 5 * 82 + 1 * 83 = 839
结果是,八进制数 1507 转换成十进制数为 839
六、十六进制转换十进制
例:2AF5换算成10进制
直接计算就是: 5 * 160 + F * 161 + A * 162 + 2 * 163 = 10997
(别忘了,在上面的计算中,A表示10,而F表示15)、
现在可以看出,所有进制换算成10进制,关键在于各自的权值不同。
假设有人问你,十进数 1234 为什么是 一千二百三十四?你尽可以给他这么一个算式: 1234 = 1 * 103 + 2 * 102 + 3 * 101 +
4 * 100
二. Java高级
1. 集合(collection)
集合:是一种拥有数组特性,但是又打破了数组局限性的一种存储数据的方式
集合的种类:
Set 集
List 列表
Map 映射
List、set、map都是接口,List、set继承了Collection接口而Map没有
Collection:List:LinkedList(实现类:链表,此实现不是同步的,底层基于链表机制来实现(适于多插删,不适于查找))
ArrayList(实现类:数组,此实现不是同步的,底层基于数组来实现(适于多查找,不适于插删))
Set:SortedSet(自动排好了顺序 接口):TreeSet(实现类,迭代(取值)无序,可以排序,此实现不是同步的,在插元素时就开始排序操作,但要有比较规则)
HashSet(实现类,迭代(取值)无序,不能排序,此实现不是同步的,利用hashcode与equals来判断对象是否相同)
Map:HashMap(实现类,此实现不是同步的,迭代(取值)无序,不能直接排序,可以通过转换成Set排序,key value允许为null,通常称为轻量级的)
Hashtable(注意t为小写)key value不允许为null,否则会发生空指针异常,此实现是同步的,通常称为重量级的
所谓实现同步就是线程同步,线程安全;否则相反。
Map
/ | \
/ | \
SortedMap Hashtable HashMap
| |
| |
TreeMap Properties
-------------------------------------------------------------------------------
List的特点:
1.输入顺序与输出顺序一致(存放对象按顺序存放)
2.可以有重复元素(数学中的集合由于元素的互异性,不存在重复元素)
3.下标也是从0开始的
Set的特点:
1.输入顺序与输出顺序不一致(存放对象不要求顺序存放)
2.不允许有重复元素
注意:
1.如果两个对象equals方法返回true,那么这两个对象的hashcode一定相等(对)
2.如果两个对象的hashcode相等,那么这两个对象一定相等(错)
3.当一个对象被存储进HashSet集合后,就不能修改该对象参与Hash运算的字段,否则会造成内存泄露
Map的特点:
存放key----->value键值对
map的迭代方法:
1.构造key的Set集合
2.迭代该集合
3.根据迭代出来的Key获取map中对应的value
注意:key值不能重复,如果key值相同,而value值不同,则会被覆盖。
Iterator迭代器:遍历的三种方式
2. 反射(reflect)
反射:JDK1.2以后出现的一种特性,反射技术在Spring,Hibernate以及Junit等等框架技术都使用了
Class类介绍:
java中的类用于描述一类事物的共性
Person类->姓名、年龄、性别...
java类中的共性->属性、方法、构造方法
Class类就是用来描述java类的共性的一个类
反射技术:就是把一个类中的各种成分映射成其相应类的技术
3. 线程(Thread)
进程和线程:
1.进程:一个应用程序在内存中的镜像
2.线程:一个进程中可以包含多个线程
通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源。
在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。
由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,
能更高效的提高系统内多个程序间并发执行的程度
如何产生线程:
第一种方式:
1.自定义一个线程类继承Thread
2.覆盖run方法
3.创建自定义线程类的对象
4.调用start方法启动线程
第二种方式:
1.自定义一个线程类实现Runnable接口
2.实现接口中的run方法
3.创建自定义线程类的对象
4.Thread thread = new Thread(threadB);
5.调用start方法
new ThreadA ---->调用start()----->CPU调用 run()
初始状态--------->可运行状态------>运行状态-------->结束状态
| |
| |-->阻塞状态
---------------|
---synchronized 同步方法或代码
锁状态-------------->synchronized
等待状态------------>wait(),notifyAll(),notify()
notifyAll:让等待某个对象的所有线程离开阻塞状态
notify:随即的选取等待某个对象的单个线程让它离开阻塞状态
wait():如果一个线程调用了某个对象的wait方法,那么该线程进入到该对象的等待池(并且已经将锁释放)
4. I/O流和文件
①File :即可以表示一个文件,又可以表示一个目录
new File(“pathname”)并不是创建一个文件,而是将某个文件与java虚拟机中的一个File类进行了一个关联。
查找某个目录下某种类型的文件
1.指定查找的路径
2.将该路径下所有的文件、文件夹查询出来
3.判断当前file.isFile()
4.如果是标准文件,判断后缀名是否是.txt
5.如果不是,返回第一步
②流的种类:
功能:输入输出流
性质:字节字符流
常用的字节流:FileInputStream(读出) FileOutputStream(写入)
DataInputStream DataOutputStream
BufferedInputStream BufferedOutputStream
常用的字符流:BufferedReader BufferedWriter
InputStreamReader InputStreamWriter
字节流读写步骤:
(写)1.创建流2.构造数据3.写数据4.关闭流
(读)1.创建流2.读取数据3.关闭
BufferedInputStream的数据成员buf是一个位数组,默认为2048字节。
当读取数据来源时,例如文件,BufferedInputStream会尽量将buf填满。
当使用read()方法时,实际上是先读取buf中的数据,而不是直接对数据来源作读取。
当buf中的数据不足时,BufferedInputStream才会再实现给定的InputStream对象的read()方法,从指定的装置中提取数据。
BufferedOutputStream的数据成员buf也是一个位数组,默认为512字节。
当使用write()方法写入数据时实际上会先将数据写到buf中,当buf已满时才会实现给定的OutputStream对象的write()方法,将buf数据写到目的地,而不是每次都对目的地作写入的动作。
BufferedReader转换到FileInputStream的步骤
BufferedReader-》Reader-》InputSreamReacder-》InputStream-》FileInputStream
③对象前加了transient关键字,则不能也不需要序列化。
5. Java新特性(5个小点、4个大点)
--自动装箱与拆箱:封箱的转换工作只有在不得已的情况下才能进行
--静态导入:
import static java.lang.Math.*;
double value = log(100)*PI;
--可变长参数
1.使用了可变长参数,就不能有重载的数组形式参数的方法
2.如果有完全匹配的重载方法,优先调用该方法,实在找不到才调用可变长参数
3.可变长参数在参数表中只能出现一次,如果有多个参数,可变长参数只能为最后一个
--格式化输出:为了符合C程序员变成习惯
-- for循环增强版:for(String str:arr)
4个大点是枚举、泛型、注释、线程安全(lock)
--枚举类型:
C语言中有枚举
MON,TUE,WED,THU,FRI,SAT,SUN
方法中使用泛型:
1.第一种方式 List> list
根据传递的list的泛型来进行操作
2.第二种方式 List extend Number> list
泛型只能是Number类或者是Number类的子类类型
3.第二种方式 List extend Comparable> list
泛型是实现了Comparable接口的类型
4.第四种方式:List super Number> list
泛型的只能是Number类型的父类
泛型使用注意事项:
1.不能new一个泛型对象
TestMyGenerics
new TestMyGenerics
2.静态方法的返回值不能为泛型
public static V getV() {
return v;
}
3.静态属性也不能是泛型类型
private static K k;
注释可以放在类,包,方法...上面
@SuppressWarnings(抑制警告)("deprecation")取消编译器警告,生命周期 源文件
@Deprecated(被反对的)生命此方法已过时 生命周期 运行时
@Override表明此方法是覆盖父类中的一个方法 生命周期 源文件
java.lang包下面有关于上面三个注释的说明
注释的应用结构:
注释类 @interface A{}
应用了注释类的类
@A
class B{}
对应用了注释类的类进行反射操作的类
注释的生命周期:
源文件--》.class--》二进制(运行时)
元注释:用来定义注释的注释
@Retention(保留):表示注释类型的注释要保留多久,它的值可以是枚举RetentionPolicy中的值
CLASS:编译器将把注释记录在类文件中,但在运行时JavaVM不需要保留注释
RUNTIME: 编译器将把注释记录在类文件中,在运行时JavaVM需要保留注释,因此可以反射性地读取。
SOURCE:编译器要丢弃的注释。
@Inherited 指注释类型被自动继承。
@Documented 指某一类型的注释将通过javadoc和类似的默认工具进行文档化。
@Target(目标):指注释类型所适用的程序元素的种类,它的值可以是ElementType中所规定的值
ANNOTATION_TYPE:注释类型声明
CONSTRUCTOR 构造方法声明
FIELD 字段声明(包括枚举常量)
METHOD 方法声明
PACKAGE 包声明
PARAMETER 参数声明
TYPE 类、接口(包括注释类型)或枚举声明
ElementType.TYPE类型,接口、注释对他们的描述Type
Class与Type比较,type的范围更宽泛
三. Java难点
1.字符串反转
public class Test{
public static void main(String[] args){
String str="安博教育";
char[] arr=str.toCharArray();
for(int i=0;i
arr[i]=arr[arr.length-i-1];//把“育”赋值给temp中“安”所在的位置,“安”被覆盖
arr[arr.length-i-1]=temp;//把temp里以前的“安”反赋值给“育”以前所在的位置
}
String str2=new String(arr);
System.out.println(str2);
}
}
2.基本数据类型与引用数据类型(String)
String str=”abc”;//字符串池
String str2=”abc”;
String str3=new String(“abc”);//堆
String str4=new String(“abc”);
System.out.println( str= =str2);//true 内存地址相同,相当于两个引用str 和str2指向同一个对象空间
System.out.println( str.equals(str2));//true 在String类中equals()被覆盖,指内容(值)相同
System.out.println( str3= =str4);//false new出来的对象空间是新的空间,所以空间地址肯定不同
System.out.println( str3= =str);// false
System.out.println( str3.equals(str));//true
在基本数据类型中:
int n=10;
int m=10;
在内存中m和n是两个独立的、不同的地址空间
3.基本数据类型与包装类之间的转换
//int -------->Integer
int n=10;
Integer n2=new Integer(n);
//jdk5.0 封箱解箱
Integer n3=n;
//Integer ------>int
//jdk5.0
int data=n3;
int data2=n3.intValue();// 调用Integer中的intValue()方法
//int----->String
int m=10;
String str=10+””;
//String----->int
int n4=Integer.parseInt(“1001”);
int n4=Integer.parseInt(“abcd”);//无法转译,错误
//Integer---->String
toString();
//String------>Integer
new Integer(String);//new一个对象,传入String类值
4.HashCode
如果是你自己定义的一个类,比较自定义类用equals和==是一样的,都是比较句柄地址,因为自定义的类是继承于object,而object中的equals就是用==来实现的,你可以看源码。
那为什么我们用的String等等类型equals是比较实际内容呢,是因为String等常用类已经重写了object中的equals方法,让equals来比较实际内容。
在一般的应用中你不需要了解hashcode的用法,但当你用到hashmap,hashset等集合类时要注意下hashcode。
你想通过一个object的key来拿hashmap的value,hashmap的工作方法是,通过你传入的object的hashcode在内存中找地址,当找到这个地址后再通过equals方法来比较这个地址中的内容是否和你原来放进去的一样,一样就取出value。
所以这里要匹配2部分,hashcode和equals
但假如说你new一个object作为key去拿value是永远得不到结果的,因为每次new一个object,这个object的hashcode是永远不同的,所以我们要重写hashcode,你可以令你的hashcode是object中的一个恒量,这样永远可以通过你的object的hashcode来找到key的地址,然后你要重写你的equals方法,使内存中的内容也相等。
HashCode是一个对象地址的门牌号,但与地址不同,就像一个寝室住的人的位置不同,人数不同一样,可以把地址看成是内容和门牌号的总和。
5.toString()详解
toString()是Object类的输出方法,在调用System.out.println()时,默认被调用,原始的toString()是输出字符串,里面的对象用相应的HashCode表示,这样我们不容易看懂,所以很多类对toString()进行了重写,例如String类,而其他一些基本数据类型的HashCode可以认为是数据本身。
6.字符串解析
①调用String类的split()方法
String str = “a=b==c=d”;
String[] arr = str.split(“=”);
For(int i=0;i
}
输出结果为: ab cd(bc之间有空格)
②引进StringTokenizer类
StringTokenizer st = new StringTokenizer(str, “=”);
While(st.hasMoreTokens()){
System.out.println(st.nextToken());
}
输出结果为: abcd(bc之间没有空格)
四.Java练习和代码(部分)
1. 利用for循环打印 9*9 表?
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
pg:
public class ChengFa{
public static void main(String[] args){
for(int i = 1;i<=9;i++){
for(int j=1;j<=i;j++){
System.out.print(j+"*"+i+"="+i*j+" ");
}
System.out.println();
}
// return ;
}
}
2. 写一个形状类Shape
有两个方法一个求周长,一个求面积
写一个长方形类Rect继承于形状类
增加属性长和宽
分别去覆盖求周长和求面积的方法
写一个圆形类Circle
增加属性半径
分别去覆盖求周长和求面积的方法
写一个测试类,在测试类中分别创建不同的对象放入进一个Shape
数组中进行,循环数组中的元素求周长和面积
Pg:
public class ShapeTest {
public static void main(String[] args) {
Rectangle r = new Rectangle(20.2,10.1);
System.out.println("矩形的周长:"+r.calculatePerimeter());
Circle c = new Circle(10.8);
System.out.println("圆的周长:"+c.calculatePerimeter());
}
}
abstract class Shape{
public abstract double calculatePerimeter();
}
class Rectangle extends Shape{
private double length;
private double width;
// public double getLength() {
// return length;
// }
// public void setLength(double length) {
// this.length = length;
// }
// public double getWidth() {
// return width;
// }
// public void setWidth(double width) {
// this.width = width;
// }
public Rectangle(double length, double width) {
super();
this.length = length;
this.width = width;
}
public double calculatePerimeter(){
return (length+width)*2;
}
}
class Circle extends Shape{
private double radius;
// public double getRadius() {
// return radius;
// }
//
// public void setRadius(double radius) {
// this.radius = radius;
// }
public Circle(double radius) {
super();
this.radius = radius;
}
public double calculatePerimeter(){
return Math.PI*radius*2;
}
}
3. 春晓 ---> 晓春
春眠不觉晓 晓觉不眠春
处处闻啼鸟 鸟啼闻处处
夜来风雨声 声雨风来夜
花落知多少 少多知落花
Pg1:
import java.io.*;
import java.util.*;
public class PoetryReader {
public static void main(String[] args) throws Exception {
FileInputStream fin = new FileInputStream("./xiao.txt");
InputStreamReader isr = new InputStreamReader(fin);
BufferedReader br = new BufferedReader(isr);
PrintWriter pw =
new PrintWriter(new FileOutputStream("./ming.txt"));
List list = new ArrayList();
String str = br.readLine();
while(str != null){
StringBuffer sb = new StringBuffer(str);
StringBuffer sb1 = sb.reverse();//字符取反
list.add(sb1);
System.out.println(sb1);
pw.println(sb1);//执行把读取的字符按行写入新文本
str = br.readLine();
}
pw.close();//一定要记得关闭流
br.close();
System.out.println("-------美丽的分割线----------");
for (int i = list.size(); i > 0; i--) {
//注意调用StringBuffer的toString()
//String a= list.get(i-1).toString();
System.out.println(list.get(i-1));
}
}
}
Pg2:
import java.io.*;
import java.util.*;
public class PoetryReader2Test {
public static void main(String[] args) throws Exception {
FileInputStream fin = new FileInputStream("./xiao.txt");
InputStreamReader isr = new InputStreamReader(fin);
BufferedReader br = new BufferedReader(isr);
PrintWriter pw =
new PrintWriter(new FileOutputStream("./ming1.txt"));
List list = new ArrayList();
String str = br.readLine();
while (str != null) {
System.out.println(str);
pw.println(str);
char[] arr = str.toCharArray();
int j = arr.length;
char[] arr2 = new char[j];
for (int i = 0; i < arr.length; i++) {
arr2[i] = arr[j - 1];
j--;
}
list.add(arr2);
str = br.readLine();
}
pw.close();
br.close();
System.out.println("-------美丽的分割线-----------");
for (int i = list.size(); i > 0; i--) {
char[] arr1 = (char[]) list.get(i - 1);
System.out.println(new String(arr1));
}
}
}
4. 编写一个接口OddInterface,提供两个方法:isOddNumber方法返回一个boolean值,判断一个数是否是奇数,getOdd方法返回一个整型数,返回被判断的数值。
编写一个类Odd 实现OddInterface,提供一个int类型的odd属性表示要被判断的数,提供一个有参的构造方法;实现OddInterface中定义的方法。
编写一个OddPrint类,打印整型数是奇数还是偶数。提供一个静态的print方法,方法的形参是OddInterface型的参数
编写OddTest测试类,在main方法中创建一个Odd对象,并调用OddPrint的静态print方法打印判断结果
pg:
public class OddTest {
public static void main(String[] args) {
Odd odd = new Odd(101);
OldPrint.print(odd);
}
}
interface OddInterface{
public boolean isOddNumber();
public int getOdd();
}
class Odd implements OddInterface{
public int odd;
public Odd(int odd) {
super();
this.odd = odd;
}
public int getOdd(){
return odd;
}
public boolean isOddNumber(){
return (odd%2==0);
}
}
class OldPrint{
public static void print(OddInterface odd){
if(odd.isOddNumber()==false){
System.out.println("该奇数为:"+odd.getOdd());
}else{
System.out.println("该偶数为:"+odd.getOdd());
}
}
}
5. 某学校希望在学生毕业的时候统计出学生在校期间考试成绩的排名,编写程序实现这样的功能:
* a) 写一个Student类,为其添加如下属性
* name:String,sid:String,gender:boolean,score:float
* b) 写一个Comparator接口的实现类,比较规则是成绩高的排在前面,成绩相同学号小的排在前面
* c) 创建多个Student对象将其添加到TreeSet集合中实现成绩排名功能
* d) 遍历输出TreeSet集合中的Student对象
Pg:
import java.util.*;
public class StudentTest {
public static void main(String[] args) {
List
list.add(new Student("1", "10001", true, 85));
list.add(new Student("2", "10002", true, 70));
list.add(new Student("3", "10003", true, 90));
list.add(new Student("4", "10004", true, 88));
list.add(new Student("5", "10005", true, 63));
list.add(new Student("6", "10006", true, 85));
list.add(new Student("7", "10007", true, 43));
list.add(new Student("8", "10008", true, 90));
Collections.sort(list,new MyComparator());
for (Student stu : list) {
System.out.println(stu);
}
}
}
class Student{
private String name;
private String sid;
private boolean gender;
private float score;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public boolean isGender() {
return gender;
}
public void setGender(boolean gender) {
this.gender = gender;
}
public float getScore() {
return score;
}
public void setScore(float score) {
this.score = score;
}
public Student(String name, String sid, boolean gender, float score) {
super();
this.name = name;
this.sid = sid;
this.gender = gender;
this.score = score;
}
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;
}
if(obj == null){
return false;
}
if(obj instanceof Student){
Student stu = (Student)obj;
return this.getName().equals(stu.getName());
}
return false;
}
public int hashCode(){
//hashcode自己定义,相同也行(如果相同,则直接比较对象内容,hashcode就没什么作用了)
return sid.hashCode();
}
@Override
public String toString() {
return this.name + "\t" + this.sid + "\t" + this.gender + "\t" + this.score;
}
}
class MyComparator implements Comparator
@Override
public int compare(Student stu1, Student stu2) {
System.out.println(stu1.getScore());
System.out.println(stu2.getScore());
if (stu1.getScore() == stu2.getScore()) {
//String类实现了Comparable接口
return stu1.getSid().compareTo(stu2.getSid());
}
return (int) (stu2.getScore() - stu1.getScore());
}
}
6. 经典person类(set get的用法)
Pg:
public class Person {
private String name;
private int age;
static{
System.out.println("person 静态代码块........");
}
{
System.out.println("person 实例代码块........");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(){
//this("andy",20);
System.out.println("person 无参构造......");
}
public Person(String name, int age) {
//super();
this.name = name;
this.age = age;
System.out.println("person 有参构造......");
// System.out.println("name = "+name+" age = "+age);
}
public static void main(String[] args) {
// Person p = new Person("andy",20);
// Person p1 = new Person();
// Person p2 = new Person();
Student1 s1 = new Student1("andy",19);
// p1.setAge(20);
// p1.getAge();
// p1.setName("andy");
// p1.getName();
// System.out.println(p1.getAge());
// System.out.println(p1.getName());
}
}
class Student1 extends Person{
private String name;
private int age;
static{
System.out.println("student 静态代码块.......");
}
{
System.out.println("student 实例代码块.......");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student1() {
System.out.println("student 无参构造.......");
}
public Student1(String name, int age) {
//super();
this.name = name;
this.age = age;
System.out.println("student 有参构造.......");
}
}
7. 判断闰年
Pg:
public class LeapYear {
public static boolean isLeapYear(int year){
return ((year%4==0 && year%100 !=0) || (year%400==0));
}
public static void main(String[] args) {
//int[] year= new int[0];
int year=2008;
/* if((year%4==0 && year%100 !=0) || (year%400==0)){
System.out.println(year+" is leap year ");
}else {
System.out.println(args[0]+" is not leap year ");
}
*/
System.out.println(isLeapYear(year)?year+" is leap year":year+" is not leap year");
int year2=2010;
System.out.println(isLeapYear(year2)?year2+" is leap year":year2+" is not leap year");
}
}
8. 获取一个类中所有的String类型的成员变量,把里面的字符e改成B
1.获取该类全部的field
2.判断所有field中类型为String
3.跟据传递进来的对象获取原String
4.修改原String变为新String
5.将修改后的String放回传递的对象中
Pg:
import java.lang.reflect.Field;
public class FieldTest {
public static void main(String[] args) throws Exception{
Person p1 = new Person("icexu",1);
// Class clazz = p1.getClass();
// //获取变量(注意变量名都是字符串形式,我们需要传入的参数就是变量名)
// Field field = clazz.getField("name");
// System.out.println(field);
// System.out.println(field.get(p1));
// Field field2 = clazz.getField("salary");
//可以获取私有变量名,但不能获取变量的值
// Field field2 = clazz.getDeclaredField("salary");
// System.out.println(field2);//获取变量名
//通过暴力函数强行获取变量的值
// field2.setAccessible(true);
// System.out.println(field2.get(p1));//获取相应变量值
System.out.println(p1);
// System.out.println("--------------------");
changChar(p1);
System.out.println(p1);
}
public static void changChar(Person person) throws Exception{
//获取Person类的所有变量
Field[] fields = person.getClass().getDeclaredFields();
//获取String类型的变量
for(Field field:fields){
if(field.getType()==String.class){
//通过暴力函数强行获取变量的值
field.setAccessible(true);
//获取旧的String类变量的值
String old = (String) field.get(person);
//用新值替换旧值
String newString = old.replace('e', 'B');
//把新值放回指定对象
field.set(person, newString);
}
}
}
}
class Person{
public String name;
private int salary;
public Person(String name, int salary) {
super();
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
@Override
public String toString() {
return this.name+"@"+this.salary;
}
}
9.给出下面的代码片段:
class Preson{
private int a;
public int change(int m){return m;}
}
public class Teacher extends Person{
public int b;
public static void main(String[] args){
Person p = new Person();
Teacher t = new Teacher();
int i ;
//point x
}
}//在point x处的哪些声明是句法上合法的
A.i =m; B.i = b; C.i=p.a; D.i=p.change(30); E.i=t.b;
//B不对是因为静态变量不能直接调用非静态变量,要通过对象来调用;C不对是因为变量a是私有的
10.运行下列程序,其输出结果如何
public class Test{
static Boolean foo(char c){
System.out.print(c);
return true;
}
public static void main(String[] args){
int i = 0;
for(foo(‘A’);foo(‘B’)&&(i<2);foo(‘C’)){
i++;
foo(‘D’);
}
}
}
A.ABDCBDCB B.ABCDABCD C.Compilation fails D.An exception is thrown at runtime
//解释:首先要搞清for循环的执行顺序,先执行初始值foo(‘A’),然后判断条件foo(‘B’)&&(i<2),条件如果满足,则执行for循环里面的语句i++; foo(‘D’);最后执行增量语句foo(‘C’);紧接着又执行判断条件,条件满足则执行for循环里面的语句i++; foo(‘D’),然后又执行增量语句foo(‘C’);如此循环,直到条件不满足为止。
11.运行下列程序,输出结果如何
class Base{
int i;
Base(){add(1);}
void add(int v){
i +=v;
}
void print(){
System.out.println(i);
}
}
class Extension extends Base{
Extension(){
add(1);
add(2);}
void add(int v){
i +=v*2;
}
}
public class Qd{
public static void main(String[] args){
bogo(new Extension());
}
static void bogo(Base b){
b.add(8);
b.print();
}
}
A.9 B.18 C.20 D.22
//解释:new了一个子类对象Extension()调用add()方法,先调用父类的构造函数Base(),注意,Base()中的add()是调用子类的add(),值为2,然后再调用子类的构造函数Extension(),在其中调用子类的add(),值为6,然后,初始化完成,再通过b.add(8)得出结果22。
12.有一个类如下:
class Test{
void test(int i){
System.out.println(“I am an int.”);
}
void test(String s) {
System.out.println(“I am an string.”);
}
public static void main(String[] args){
Test t=new Test();
char ch=’y’;
t.test(ch);
}
}
//输出结果为:I am an int.
//解释:char类型可以自动转换成int,char与String是有区别的
13. 运行下列程序,输出结果如何
public class Test{
public static void main(String[] args){
String word=”restructure”;
System.out.println(word.substring(2,3));
}
}
A.est B.es C.str D.s
//解释:substring(int beginIndex,int endIndex)下标从0开始,所获取的字符长度为3-2=1
14.打印10行杨辉三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
Pg:
public class YangHui {
public static void main(String[] args) {
int a[][]=new int[10][];//创建一个二维数组用来保存杨辉三角的值
for(int i=0;i
}
for(int i=0;i
a[i][j]=1;
else
a[i][j]=a[i-1][j-1]+a[i-1][j];
}
}
for(int i=0;i
System.out.println();
}
}
}