Day01 Day02Java到底有哪些优势?1.跨平台(平台=OS) 可移植性在不同的操作系统之上可以不用做任何代码的修改直接使用a) 字节码文件:字节码文件不包括任何内存布局信息 与操作系统和硬件毫无关系 (Java的内存分布是在运行的时候才动态分配的)b) JVM:真正解释字节码文件内容并且和操作系统交互的部分 Sun(Oracle)已经给每一款操作系统都写好了现成的JVM JVM组成部分: 类加载器 ClassLoader 字节码校验器 解释执行器 (翻译)逐行的解释执行代码2.安全 健壮3.面向对象 面向过程: 程序:函数+变量 (算法+数据结构) 面向对象: 如:SmallTalk程序:对象和对象相互之间的“通讯”对象:属性和方法 类: 创建对象的模板 具有相同特征的一类事物的高度抽象集合概念对象是类的实例化,类是对象的抽象化引用 4.动态更新 5.简单! 没有指针和相关的内存操作 new 内存操作gc 内存回收清理 Java中的回收机制:零引用回收 问题: System.gc(); Runtime.getRuntime().gc(); 调用gc的下一行是否回收?不一定6.免费 开源 搭建Java开发平台1.JDK (JavaSDK java开发工具包) SDK(软件开发工具包) JDK安装 JDK 1.5 5.0 猛虎 JDK 1.6 6.0 野马 JDK 1.7 7.0 海豚 JDK JRE JVM JDK Java开发工具包 JRE Java运行环境 JVM Java虚拟机 JDK = JRE + 常用工具 JRE = JVM + 核心类库 JVM = 三部分2.设置环境变量我的电脑-属性-高级-环境变量为了使开发过程变得更加简单快捷(问题:搭载Java开发平台最少设置几个环境变量?零个。
为了方便,不是必要 环境变量名字给谁用做什么用PATH操作系统更快的找到程序CLASSPATHJVM(类加载器)找到字节码文件JAVA_HOME其他Java程序找到JDK a) PATH 就是为了在任何一个目录下都可以直接访问bin目录下的工具(命令)C:\Program Files\Java\jdk1.6.0_06\binb) CLASSPATH 默认值: . (当前目录) c) JAVA_HOME 设置到JDK安装目录下JAVA_HOME:JDK安装目录下 CLASSPATH:. PATH:%JAVA_HOME%\bin *环境变量名字最好全部大写*在CMD设置环境变量时=左右两边不要加空格 *在CMD中定义任意程序环境变量:如:set PATH=E:\TTPlayer同时定义两个环境变量中间加分号,或者Set PATH=%PATH%;E:\TTPlayer分号后面不能加空格3.Java运行过程:编译期:Java源文件.java编译为字节码文件.class 运行期:JVM --OS硬件编写代码HelloWorld 如何编译java程序 javac 源文件的名字.java 如何运行java程序 java 类名(没有扩展名)HelloWorld.java代码:public class HelloWorld{ public static void main(String[] args) { System.out.println("Hello!!"); }}public 修饰符 modifier static 修饰符 静态(不用通过对象调用)void 方法返回值(表示这个方法不需要返回值)main 标识符标识符 Identifier1.必须是英文 _ $ 中文开头2.不能使用有特殊意义的名字(关键字)类名(接口名):每个单词首字母大写属性名和方法名:首字母小写,之后每个单词首字母大写包名:全部小写The most common relationships between classes are• Dependence (“uses–a”)• Aggregation (“has–a”)• Inheritance (“is–a”)类成员:类可以拥有三种成员:·字段:它们是类及其对象相关联的数据变量,保存着类或者对象的状态。
·方法:它们包含类的可执行代码并定义了对象的行为·嵌套类(nested class)与嵌套接口(nested interface):它们是在其他的类或接口声明的内部声明的类与接口类修饰符:·注解(annotation)·public :任何人都可以声明对这种类的对象的引用,或者访问这种类的公共成员·abstract:抽象类,被认为是不完整的,所以我们不能创建抽象类的实例通常这是因为抽象类包含abstract方法,这些方法必须在子类中实现·final:final类不允许拥有子类类不能既是final的又是abstract的·严格浮点(strict floating point): 声明为strictfp的类要求类中的所有浮点运算都是精确运算Java当中的包(对应操作系统当中的目录) 1.区分不同的命名空间 2.对多个.class文件进行分类的归类 编译语句:javac -d . HelloWorld.java -d 自动创建源文件当中指定的包结构 . 在当前目录下创建目录结构运行语句: java 包名.类名通过包名和类名来唯一确认一个类 打包语句:package 导包语句:import例:打包,源文件Student.java放在桌面,为了能够运行,定义主方法mainpackage iii.ii;public class Student{ public static void main(String[] args) { System.out.println("Hello!"); }}编译:打开CMD,输入“cd 桌面”转到当前目录,编译语句: javac –d . Student.java运行:java iii.ii.Student(通过包名+类名唯一确定一个类)例:导包,先写一个打包文件:package iii.ii;public class Student{ public static void SayHello() { System.out.println("Hello!"); }}编译:javac –d . Student.java然后写导包文件:import iii.ii.Student;public class Hello{ public static void main(String[] args) { Student.SayHello(); }}编译:javac Hello.java运行:java Hello生成帮助文档的常用工具 javadoc 语句: javadoc -d doc 源文件的名字.javaJava注释:单行注释 /多行注释 /* */文档注释 /** */生成jar包 jar包就是java当中可执行的压缩归档文件 1.可执行 2.压缩3.归档 一个java程序可能涉及到很多个.class 把它们都归纳在一起 变成一个文件 生成jar包语句:jar cvf 名字.jar 要放进压缩文件里的文件 c 创建新的归档文件 v 标准输出设备显示详细列表信息 f 指定归档文件的名字生成可执行Jar包具体步骤: 1 写.java文件如,写一个无限弹出计算器的代码 public class Test{ public static void main (String[] args)throws Exception { while(true) Runtime.getRuntime().exec("calc"); }} 2 编译.java生成.classjavac Test.java 3 将class文件打到jar包当中 jar cvf name.jar Test.class 4 修改jar当中的清单文件,在第三行加入 Main-Class: Test 注意:Test前面有空格(终止程序的方法:在CMD中输入tskill javaw)变量编程语言当中肯定要定义很多很多的变量来存储数据 变量分类: 1.定义在类体当中的变量 成员变量 实例变量public class HelloWorld{ int i =100;//成员变量 属性 HelloWorld类型的对象都有一份的属性 public static void main(String[] args) { System.out.println(i); }} 组成类的对象的属性依靠对象来存在的 它是对象存储空间当中的一部分 实例变量使用前不用初始化 2.定义在方法体中的变量 局部变量 在自己所在的方法体当中可以使用 出方法体 消亡 局部变量使用之前一定要初始化 *局部变量和成员变量是可以重名的!在局部变量所在的方法体中直接出现变量名将代表局部变量public class TestStudent{ public static void main(String[] args) { Student stu = new Student(); stu.setAge(25); System.out.println(stu.age); }}class Student{ int age; String name; public void setAge(int age)// { //stu.age = 25; this.age = age;//实例变量和局部变量出现重名的时候,如果不写this.则这句没有意义,打印age的默认值0 }}数据类型 1.基本数据类型 primitive types 8种 boolean char byte short int long float doubleFloating-point numbers without an F suffix (such as 3.402) are always considered to be of type double.If you want to round a floating-point number to the nearest integer (which is the more useful operation in most cases), use the Math.round method:double x = 9.997;int nx = (int) Math.round(x);Now the variable nx has the value 10. 1.boolean 布尔型 true / false 2.char 字符型 3.整数型 (符号位 数值位) byte 8位 -128 ~ 127 short 16 - 215 ~ 215 -1 int 32 * long 64 即-2 (n-1) ~ 2(n-1)-14.浮点型 (符号位 幂指位 数值位) float 32位 double 64位 *2.引用数据类型(自定义类型 对象类型) 无数种byte short (char) int long float double自动提升(就近提升)强制类型转换这种类型提升的规则,对于方法参数匹配同样适用public class Test{ public static void main(String[] args) { boolean flag = true; System.out.println(flag); char c1 = '中'; char c2 = 97; char c3 = '\u0000'; char c4 = '\t'; byte b1 = 1; byte b2 = 2; byte b3 = (byte)(b1+b2);//int类型 强制类型转换 int i1 = 45; int i2 = 031;//8进制 int i3 = 0x31; //16进制 long l1 = 1; long l2 = 1L; float f1 = 0.1F; double d1 = 0.1D; }}public class TestDataType{ public static void main(String[] args){ int i=10; get(i); } public static void get(byte a){ System.out.println("我是byte型"); } public static void get(long b){ System.out.println("我是long型"); } public static void get(double c){ System.out.println("我是double型"); }}运行结果:我是long型 (方法参数匹配就近提升)public class DataType{ public static void main(String[] args){ int i=10; long d=get(i); System.out.println(d); //打印long类型的20 } public static int get(double a){ return (int)a; } public static int get(byte b){ return b; } public static int get(float c){ return (int)c*2; //自动就近提升,所以调用这个方法,因为返回值为int型,所以代码中要强制类型转换 }}short a = 1;a = a + 1;编译错误,a+1运算结果是int型,需要强制转换类型short a = 1; a += 1;可以正确编译public class TestArguments{ public static void main(String[] args) { byte i = 1; get(i);//方法的调用 } public static void get(short d)//方法的定义,方法的参数作为局部变量 { //short d = i;如果再写这句就重复定义 System.out.println(d); }}public class TestArgs{ public static void main(String[] args) { Car benz = new Car(); benz.number = 99999; changeNumber(benz); System.out.println(benz.number); } public static void changeNumber(Car car) { //Car car = benz;//Java当中只有值传递 car.number = 88888; }}class Car{ int number;}画图:运行结果:88888public class TestExec{ public static void main(String[] args){ IntA ia = new IntA(); ia.i = 55; change(ia); System.out.println(ia.i); } public static void change(IntA ib) { //IntA ib = ia; ib = new IntA();//如果去掉这句则同上一个例子,运行结果为99 ib.i = 99; }}class IntA{ int i;}画图:运行结果:55public class Exec{ private static int j = 0; private static boolean methodB(int k) { j += k;//j=4; return true; } public static void methodA(int i) { //int i = 0; boolean b; b = i < 10 | methodB(4);//逻辑非短路 b = i < 10 || methodB(8);//逻辑短路运算符 第二个表达式不必进行判断 } public static void main(String args[]) { methodA(0); System.out.println(j);//4 }}public class TestOperator{ public static void main(String[] args) { /* + - * / % */ System.out.println( -5 % 2 );// % 最终结果取决于被模数的符号,打印-1 /* += -= *= /= %= */ byte b1 = 127; b1 += 10;//b1 = b1 + 10; =左边是byte 类型 整个表达式依然是byte类型,打印-119 System.out.println(b1); /* > < >= <= == != */ int i = 1000; System.out.println( !(i>=1000)); // 编程语言当中 = 赋值运算符 == 判断是否相等,打印false /* 逻辑非短路运算符:& | 逻辑短路运算符: && || */ System.out.println( i>2000 && i<5000);//打印false /* ++ -- */ int k = 2; System.out.println(++k);// 如果k++:打印2 ++k:打印3 System.out.println(k);// 打印3 System.out.println(k++ + ++k);//k++ 3 k=4 ++k 5 k=5,打印8 /* ++ -- && || & | */ int m = 10; boolean flag = (m++>=10 || ++m>3); System.out.println(m);//打印11 /* instanceof 格式:一个引用 instanceof 一个类 左边引用所指向的对象是否是右边类型的一个实例 System.out.println(stu instanceof Student); */ /* 1 ? 2 : 3 三目运算符 */ int ii = 5; System.out.println(ii>10 ? 100.0 : 1000);//自动提升为三个数值中的最大类型,这里打印1000.0 TestOperator.absolute(3); } public static void absolute(int number) { System.out.println( number>=0 ? number : -number ); }}运算符优先级转义字符Day03流程控制分支:if else else与最近的if构成一组 switch case循环:for while do while 循环标签:break continuepublic class TestSwitchCase{ public static void main(String[] args) { int i = 5; switch(i)//byte short char int 不能在括号里定义i { case 1:System.out.println("i是1");break; case 2:System.out.println("i是2");break; case 3:System.out.println("i是3");break; case 4:System.out.println("i是4");break; default:System.out.println("i不是1234");break; } }}public class TestFor{ public static void main(String[] args) { //程序当中相邻的相似的代码肯定可以简化 //打印1到20之间所有的偶数 for(int i = 1; i <21; i++) { if(i%2==0){ System.out.println(i); } } }}public class TestWhile{ public static void main(String[] args) { int i=1; for(i = 100; i>0 ; i--) { System.out.println(i); } System.out.println(i);//这句代码已经出for循环,for 循环上面必须定义i/* for循环是while循环的便捷形式*/ i = 100;// for 1 while(i>0)//for 2 { System.out.println(i);//for 4 i--;//for 3 } }}public class TestDoWhile{ public static void main(String[] args) { int i = 9; do { System.out.println("能看到我吗?"); //无论条件是否成立 循环体首先要执行一次 } while(++i==10); }}public class TestBreakContinue{ public static void main(String[] args){ for(int i = 10;i>0;i--){ if(i==3) { //continue;//结束当次循环 直接开始下次循环 break;//结束break所在的循环 } System.out.println(i); } System.out.println("循环已经执行结束"); }}/* 打印1-100之间所有的质数(素数)*/public class TestZhiShu{ public static void main(String[] args) { System.out.println(2); for(int i = 3;i<=100;i+=2) { if(checkNumber(i)) { System.out.println(i); } } } public static boolean checkNumber(int number) { if(number==1) { return false; } for(int i = 3; i<=(number/2) ; i+=2) { if(number%i == 0) { return false; } } return true; }}public class ForExec{ public static void main(String[] args) { outer:for(int i = 1;i<6;i++) { inner:for(int j = 1;j<6;j++) { if(i==3) { break outer; } System.out.println("i="+i+"\t j="+j); } } }}/* 判定公历闰年遵循的规律为: 四年一闰,百年不闰,四百年再闰. 公历闰年的简单计算方法:(符合以下条件之一的年份即为闰年) 1.能被4整除而不能被100整除。
如2004年就是闰年,1900年不是) 2.能被400整除如2000年是闰年) 题目:判断年份是不是闰年,有三次输入机会*/import java.util.Scanner; //扫描仪public class TestLeapYear{ public static void main(String[] args){ int i=0; while(i++<3){ switch(i){ case 1:System.out.println("我是灯神,给你三次机会,请输入你要判定的年份:");break; case 2:System.out.println("哈哈,你还有两次机会,说出你要判断的年份:");break; case 3:System.out.println("你还有最后的机会,输入你要判断的年份吧:"); } Scanner sc=new Scanner(System.in); //从标准输入设备建立一个扫描仪 int year=sc.nextInt(); //从扫描仪得到一个整数 if((year%100!=0&&year%4==0)||year%400==0){ System.out.println("神灯显灵吧!答案是:This year is a leap year!\n"); } else{ System.out.println("神灯显灵吧!答案是:This year is not a leap year!\n"); } } }}使用Scanner需要先导包:import java.util.*;Whenever you use a class that is not defined in the basic java.lang package, you need to use an import directive.注意:Comparable属于java.lang Comparator属于java.util (使用前import) public class TestNine{ public static void main(String[] args) { outer:for(int i=1;i<=9;i++) { inner:for(int j=1;j<=9;j++) { System.out.print(j+"×"+i+"="+(i*j)+"\t"); if(j==i) { System.out.println(); continue outer;//或者用break; } } } }}Day04 数组import java.util.*;public class TestMay162{ public static void main(String[] args){ //Java当中的数组 存储空间等大而且连续 //数组和它存放什么类型的数据没有任何关系 数组就是引用类型的 int[] a=new int[5]; //可以通过for循环初始化数组或者遍历数组;数组的length属性 标示它当中有几个存储空间 for(int i=0;i
第100个人拉所有能把100整除的房间里的灯问:最后哪些灯是亮的(考虑实现效率!)public class TestLight{ public static void main(String[] args){ Light[] room=new Light[100]; for(int i=0;i<100;i++){ room[i]=new Light(); } for(int human=1;human<=100;human++){ for(int number=1;number<=100;number++){ if(number%human==0) room[number-1].pull(); } } for(int i=0;i<100;i++){ if(room[i].isOn) System.out.println("第"+(i+1)+"个房间的灯是亮的"); } }}class Light{ boolean isOn; //boolean型默认值是false public void pull(){ isOn=!isOn; }}3. 验证哥德巴赫猜想:任何一个大于6的偶数能够拆分成两个质数相加的和/*分析模拟拆分的过程 10: 2 8 X 3 7 right 4 6 X 5 5 right*/import java.util.*;public class GoldbachConjecture{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); System.out.println("为了验证哥德巴赫猜想请输入一个大于6的偶数:"); int number=sc.nextInt(); while(number<=6||number%2!=0){ System.out.println("你输入的数据不合法,请重新输入:"); number=sc.nextInt(); } for(int i=2;i<=number/2;i++){ if(check(i)&&check(number-i)){ System.out.println("你输入的数字是两个质数"+i+"和"+(number-i)+"的和"); } } } public static boolean check(int num){ for(int i=2;i<=num/2;i++){ if(num%i==0){ return false; } } return true; }}4. 验证数学黑洞问题:任意一个4位数,只要不是4位都相同的,那么取它最大排列组合减去最小排列组合,得到的数再取最大排列组合减去最小排列组合,依次类推,不超过7次则肯定会得到数字6174import java.util.*;public class TestBlackHole{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); System.out.println("为了验证数学黑洞,请输入一个四位数字,且四位不相同:"); String number=sc.next(); while(!number.equals("6174")){ int max=getMax(number); System.out.println(number+"的最大排列组合是:"+max); int min=getMin(number); System.out.println("最小排列组合是:"+min); number=max-min+""; System.out.println("二者想减得到的新数字为:"+number); } } public static int getMax(String str){ char[] nums=str.toCharArray(); Arrays.sort(nums); StringBuilder builder=new StringBuilder(new String(nums)); builder.reverse(); int ok=Integer.parseInt(builder.toString()); return ok; } public static int getMin(String str){ char[] nums=str.toCharArray(); Arrays.sort(nums); String s=new String(nums); int ok=Integer.parseInt(s); return ok; }}关于二维数组:Java当中的二维数组其实就是数组(引用类型)的数组,下面一段代码定义了一个存放不同个数元素的数组的数组int[][] iset = new int[7][];iset[0] = new int[3];iset [1] = new int[3];iset [2] = new int[4];iset [3] = new int[3];iset [4] = new int[3];iset [5] = new int[2];iset [6] = new int[2];图示:Day05 面向对象三大基本特征封装(encapsulation)继承(inheritance)多态(polymorphism)public class TestEncap{ public static void main(String[] args){ Human hm = new Human(); hm.setAge(30); System.out.println(hm.getAge()); }}class Human{ private int age; private String name; public int getAge(){ return age; } public void setAge(int age){ //this 当前对象 调用这个方法的对象 this.age = age; } public void eat(){ System.out.println("吃饭"); }}//继承:Java中的类只有单根继承。
父类有,相当于子类也有可以继承父类中的属性和方法,不能继承构造方法public class TestKFC{ public static void main(String[] args){ 餐厅 kfc = new 餐厅(); kfc.name = "肯德基山大路店"; Japanese xiaoQuan = new Japanese(); Chinese zhangFei = new Chinese(); English xiaoBei = new English(); kfc.service(xiaoQuan); kfc.service(zhangFei); kfc.service(xiaoBei); }}class 餐厅{ String name; public void service(People peo){ System.out.println("提供食物"); }}class People{ int age; String name;}class Japanese extends People{}class Chinese extends People{}class English extends People{}/* 方法重载!Overload 发生在同一个类当中,(返回类型可以不同),方法名相同,参数列表不同(参数列表不同:1.类型不同2.个数不同3.顺序不同) 下面这段代码编译时出错,要清楚如何编译、多态、方法重载、方法覆盖!*/public class TestOverload{ public static void main(String[] args){ A bb = new B(); bb.get(10); //因为编译的时候只看左边,上一句中bb会被当做A类对象,而A类里没有含参数的get方法 }}class A{ public void get(){ System.out.println("abc"); }}//下面这一段不是方法重载!因为发生在两个类里!class B extends A{ public void get(int i){ System.out.println("cba"); }}/* 方法覆盖!Override 发生在有继承关系的两个类之间 子类当中 出现了与父类当中返回类型相同 方法名字相同 参数列表相同的两个方法 * 访问控制权限修饰符只能越来越大 * 抛出的异常只能越来越少(小)*/public class TestOverride{ public static void main(String[] args){ //父类类型,子类对象 A bb = new B(); bb.earnMoney(); }}class A{ public void earnMoney(){ System.out.println("下海经商"); }}class B extends A{ //方法覆盖(override) public void earnMoney(){ System.out.println("好好学Java"); super.earnMoney();//调用父类当中的earnMoney()方法 }}重载和覆盖是两个针对方法的概念,属性没有重载和覆盖的概念!方法覆盖前使用:@Override防止方法覆盖语法错误多态:对象是客观存在的,不会因为改变称呼他的方式而随之发生变化1.动态多态 (父类类型 子类对象)2.静态多态 编译时多态 (Java当中的方法重载 Overload )public class TestSuper{ public static void main(String[] args){ B baby = new B(); baby.display(); }}class A{ int i = 100; public void display(){ System.out.println("A类的display方法"); }}class B extends A{ int i = 1000; public void display(){ System.out.println(this.i);//打印当前对象的i属性 谁调用display谁就是当前对象 System.out.println(super.i);//打印当前对象的父类对象的i属性 super.display(); }}图示:构造器(constructor)/* 构造器:在构造对象的时候需要调用.构造器没有返回类型 名字要和类名完全一样 Java当中 每个类都有构造器 构造器通常用来 初始化实例变量(属性) 构造器可以重载,但不能被继承,更不能被覆盖! 构造器的第一句肯定是super();或this(); 无参的构造器默认第一句super();*/public class TestConstructor{ public static void main(String[] args){。