就这样,开始了我的Java学习之旅!
学习Java之前,面临三大问题:why,what,how。
why
它具有简单,面向对象,稳定,与平台无关,解释型,多线程,动态等特点。
市场大:目前,java语言市场占有率达20%,为世界第一编程语言。我国软件行业每年所需的java人才达30万,并且每年以22%左右的速度增长着。由此看来,java发展市场无限大。
企业级应用平台的霸主:Java是一种被广泛使用的网络语言,java程序能广泛运用于金融、电信、医疗等大型企业,成为名副其实的企业级应用平台霸主。
what
Java是一种面向对象的程序语言,有三大特性:数据封装、继承、多态;
Java是一种分布式程序语言,Java特地为互联网而设计的,它有一个庞大的网络类库java.net支持各种网络阶层的联系;
Java是一种跨平台的程序语言,在不同的操作系统安装不同的java虚拟机,从而实现跨平台;
Java是一种多线程的语言;
Java是一种网络语言,它能够从网络的全球资源地址去得你所有的资源,包括数据文件、影响文件、声音文件等到你的计算机并加以处理;
Java是一种Web的程序语言,java的程序编译后可将类别文件及相对应的网页文件放置于网络服务器上,在网络上的任何计算机均可通过支持Java的浏览器加以执行。
how
前已转载一前辈高人的文章,觉得很不错,在此就不多啰嗦了。
接下来开始进入学习!
Java体系分为:java SE、java EE、java ME三大体系,很显然,我得先学java SE。而在学此之前,根据以前的经验,学习一种语言得有工具。从此我结识了JDK、Eclipse、EditPlus、另外还有老相好记事本。
开发工具的搭建
1、下载JDK(Java开发工具包)
2、环境变量配置:path、classpath 【 其中会遇到一些问题,不过百度、看视频都有的】
3、学习一些简单的DOS命令。
工具好了就开工呗!内容整体分为三大块:基础程序设计、面向对象程序设计、应用程序设计。
基础程序设计
其内容跟C语言大体相似,主要内容为:关键字、标示符、常量、变量、基本数据类型、运算符、注释、控制语句、函数(方法)、数组、字符串。
一,关键字、标示符
1,标示符的命名规范
常量:字母大写,两字母之间用“_”隔开,如:MAX_VALUE;
变量:字母小写,如:name;
方法:首字母小写,其他单词首字母大写,如:addData;
类 :如:RandomAccessFile;
接口:同类
包 :小写
一般命名不使用中文。
二,常量、变量
1,变量的有效范围
变量分为,
成员变量:在类中声明,整个类中有效。类的成员变量分两种,
a, 静态变量(类变量):有效范围是整个类,被类的所有实例所共享。生命周期在于类
b,实例变量:有效范围是整个实例,生命周期在于实例
局部变量:在方法内或方法内代码块(即“{ }”)中声明,在代码块中有效(也包括类方法的参数)生命周期在于方法。
三,基本数据类型
byte、short、int(默认)、long、float、double、char、boolean。
1,注意默认值
2,注意个数据类型的精度
3,基本数据类型之间的转换
自动转换类型: byte——>short——>int(默认)——>long——>float——>double
强制转换类型:由高精度向低精度转换,要注意可能会出现损失精度的情况。如:int b=6;byte a=(byte)b;
4,char类型解析
char的初始化
char是Java中的保留字,与别的语言不同的是,char在Java中是16位的,因为Java用的是Unicode。不过8位的ASCII码包含在Unicode中,是从0~127的。
Java中使用Unicode的原因是,Java的Applet允许全世界范围内运行,那它就需要一种可以表述人类所有语言的字符编码。Unicode。但是English,Spanish,German, French根本不需要这么表示,所以它们其实采用ASCII码会更高效。这中间就存在一个权衡问题。
因为char是16位的,采取的Unicode的编码方式,所以char就有以下的初始化方式:
char c='c'; 字符,可以是汉字,因为是Unicode编码
char c=十进制数,八进制数,十六进制数等等; //可以用整数赋值
char c='\u数字'; 用字符的编码值来初始化,如:char='\0',表示结束符,它的ascll码是0,这句话的意思和 char c=0 是一个意思。
关于char占几个字节的问题如下:
“字节”是byte,“位”是bit ;
1 byte = 8 bit ;
char 在java中是2个字节。java采用unicode,2个字节(16位)来表示一个字符。
5,java是强语言类型
四,运算符
算术运算符:+ ,-,*,/,%
关系运算符:>,<,<=,>=,==,!=
逻辑运算符:!,&&,&,||,|【单与:两边皆运算(非短路);双与:左假即出结果(短路)。”或“同理】
按位运算符:&,|,^,~(与,或,异或,取反)
移位运算符:<<,>>,>>>(左移,右移,无符号右移) 【异或可用于两数交换】
赋值运算符:=,+=,-=,*=,/=,%=,>>=,>>>=
三元运算符:(布尔表达式)?表达式1:表达式2 【类似if选择语句】
逗号运算符:,
转型运算符:如:(int)
字符串运算符:+
五,控制语句
1,if-else
2,switch
switch() //()中可为char,byte,int,short,long { case 1: //书写可无序,执行先case,后default,另注意break case 2: default: }
3,for(初始化表达式;循环条件表达式;循环后的操作表达式)
4,while,do- while
5,break:只能用在switch和循环语句中,if中用break,是用来控制循环的
6,continue(从此继续循环,结束本次循环,继续下次):只用于循环语句中
7,return:从一个方法返回,并把控制权交给调用它的语句
7,foreach语句,foreach不是关键字,一般格式如下
for(元素变量:遍历对象) { 循环体 //为了方便地遍历数组中的元素 } int array[]={1,2,3,8,9,5,6}; for(int i:array) { System.out.println(i); //"i"指的是第i个元素 }
六,函数(方法)
1,定义在类中具有特定功能的一段独立小程序
2,格式:
修饰符 返回值类型 函数名(参数) { 执行语句; return 返回值; //明确参数,返回值很重要 }
3,方法的重载
重载特点: 1、在同一类中;2、方法名相同; 3、参数列表不同(类型、个数、顺序) 4、与访问修饰符,返回值,抛出异常无关 class Test { public static void main(String[] args) { A a=new A(); System.out.println(a.add(4,5)); } } class A { int add(int a,int b) { return a+b; } double add(double a,double b) { return a+b; } }
七,数组
1,是数据类型相同的一组变量;
2,声明数组,如:
int [] array; //两种写法风格不一样而已,不过貌似也有点小不同, 或 //可参考http://blog.csdn.net/hlw881008/article/details/5503835 int array []; //大多数程序员习惯用前者
3,创建数组,如:array=new int[3];
4,初始化数组,有三种方式:int [] array=new int[3]; int [] array=new int[]{1,2,3}; int [] array={1,2,3,};
5,多维数组
6,操作数组:
a,复制数组
class Thinking { public static void main(String[]args) { int [] arr1={1,2,3,4,5,6,7,8,9}; int [] arr2=new int[10]; System.arraycopy(arr1,0,arr2,1,arr1.length); /*arraycopy(来源数组,来源数组起始位置,目标数组,目标数组起始位置,复制的元素个数)*/ for(int i=0;i<arr2.length;i++) { System.out.print(arr2[i]+" "); } } }
b,排序数组
import java.util.Arrays; public class Thinking { public static void main(String[] args) { int[] s={4,5,61,3,2,4,26,21,2,-82,34}; Arrays.sort(s); for (int i :s) { System.out.println(i); } } }
c,比较数组
import java.util.Arrays; public class Thinking { public static void main(String[] args) { int[] s={4,5,61,3,2,4,26,21,2,-82,34}; int[] y={}; System.out.println(Arrays.equals(s,y)); }
d,搜索数组
import java.util.Arrays; public class Thinking { public static void main(String[] args) { int[] s={4,5,61,3,2,4,26,21,2,-82,34}; System.out.println(Arrays.binarySearch(s,21)); } }
e,填充数组
import java.util.Arrays; public class Thinking { public static void main(String[] args) { int[] s={4,5,61,3,2,4,26,21,2,-82,34}; Arrays.fills(s,11); for (int i :s) { System.out.println(i); } } }
f,传递数组
八,字符串
1,在字符串中使用特殊字符
2,字符串的高级处理
a,比较两个字符串
class Test { public static void main(String[] args) { String a="paino"; String b="animal"; System.out.println(b.equals(a)); } }
b,确定字符串长度
class Test { public static void main(String[] args) { String a="paino"; System.out.println(a.length()); } }
c,改变字符串大小写
class Test { public static void main(String[] args) { String a="painoPjagjaKSJ"; System.out.println(a.toUpperCase()); System.out.println(a.toLowerCase()); } }
d,查找字符串
class Test { public static void main(String[] args) { String a="painoPjagjaKSJ"; System.out.println(a.indexOf("o",3)); } } //indexOf区分大小写,返回值为int
九,注释
1,单行注释 //
2,多行注释 /* */
3,文档注释 /***/
4,注释十分重要,建议初学者开头可如下:
/* *需求: *思路: *步骤: */ 程序编辑
面向对象程序设计
一,类、对象
1,类是一个抽象的概念,表示一个具有相同属性和方法的多个对象的集合,是一个有共同性质的群体,它是对象的母版。它是对象的蓝图,会告诉虚拟机应该创建某种类型的对象。
[修饰符] class <类名> [extends 父类名] [implement 接口列表] { [修饰符] [static] [final] [transient] [volatile] <变量类型> <变量名>; [修饰符] [返回值类型] <方法名> (参数列表) { [final] <变量类型> <变量名>; } }
2,对象,所谓“万物皆对象”,指的是具体的一个实实在在的东西。它是靠类的模型塑造出来的。对象已知的事物【属性】,是会执行的动作【方法】。
3,如何使用对象
你需要两个类即可:一是创造对象的类,二是使用对象的类。
class Cat //对象的母版 { String name; //属性 int age; void speak() //方法 { System.out.println("Hello!") } } class Test //使用对象的类 { public static void main(String[]args) //程序主函数 { Cat c = new Cat(); //创建一个对象 c.speak(); //使用对象 } }
4,类类型参数、匿名对象
匿名对象其实就是定义对象的简写格式,作用:a,对象对方法仅进行一次调用时可用; b,作为实际参数使用
class Cat { void speak() { System.out.println("hello"); } } class Test { public static void main(String[]args) { Cat c = new Cat(); //若表示为 method(new Cat());则使用的是匿名对象 method(c); } public static void method(Cat c) //将Cat类作为一个参数使用 { c.speak(); } }
5,构造函数
a,特点:函数名与类名相同,无返回值,不用定义返回类型(void也不行)
b,作用:给对象进行初始化
c,默认构造函数,在类中没有明确定义的情况下
d,重载
class Cat { int age; String name; Cat(int age,String name) { this.age=age; this.name=name; } Cat(String name,int age) //两参数改变一下顺序 { this.age=age; this.name=name; } } class Test { public static void main(String[]args) { Cat c=new Cat(4,小花); Cat d=new Cat(小黑,2); System.out.println(c.name+"的年龄"+c.age); System.out.println(d.name+"的年龄"+d.age); } }
6,this关键字
this的用法 a、当全局变量跟局部变量重名时,表示使用全局变量(此时this指代本类对象) class A{ String name; void setName(String name){ this.name = name; } } b、构造方法相互调用,此时this指代本类类名。注意this只能放在构造方法第一句 class B{ String name; B(){ this("name");//会自动调用带String参数的构造方法 } B(String name){ this.name = name; } } c、this是指当前对象自己。 当在一个类中要明确指出使用对象自己的的变量或函数时就应该加上this引用。 public class Hello { String s = "Hello"; public Hello(String s){ System.out.println("s = " + s); System.out.println("1 -> this.s = " + this.s); this.s = s; System.out.println("2 -> this.s = " + this.s); } public static void main(String[] args) { Hello x=new Hello("HelloWorld!"); } } d. 把this作为参数传递 当你要把自己作为参数传递给别的对象时,也可以用this。 public class A { public A() { new B(this).print(); } public void print() { System.out.println("Hello from A!"); } } public class B { A a; public B(A a) { this.a = a; } public void print() { a.print(); System.out.println("Hello from B!"); } } e、在构造函数中,通过this可以调用同一class中别的构造函数,如 public class Flower{ Flower (int petals){} Flower(String ss){} Flower(int petals, Sting ss){ //petals++;调用另一个构造函数的语句必须在最起始的位置 this(petals); //this(ss);会产生错误,因为在一个构造函数中只能调用一个构造函数 } } 值得注意的是: 1:在构造调用另一个构造函数,调用动作必须置于最起始的位置。 2:不能在构造函数以外的任何函数内调用构造函数。 3:在一个构造函数内只能调用一个构造函数。
7,static关键字
a、特点: 1、用于修饰成员 2、随着类的加载而加载 3、优先于对象存在,被所有对象所共享 4、可直接被类名调用 b、修饰成员变量:当对象中所具备的成员变量的值都是相同的,可用。【类变量】 c、修饰方法:当函数无需访问对象特有数据时可用 d、静态代码块:只执行一次,给类进行初始化 static { System.out.println("静态代码块"); } e、构造代码块:对所有对象进行初始化 注:有关Java中普通代码块,构造代码块,静态代码块区别及代码示例详情可参考: http://www.cnblogs.com/sophine/p/3531282.html
二,内存
说到这里,我觉得,我们有必要了解Java虚拟机在运行程序时是如何分配内存的。这对我们理解程序运行有很大的帮助。
详情可以关注我的另一篇Blog《Java内存浅析》http://wuyunncu.blog.51cto.com/5978596/1583962
三,继承
1,继承可以说是最大限度地发挥面向对象的可复用性,它是这样一个过程,让一个类B去继承另一个类A,那么被继承的类A里的一些公开的可以被B看到的东西都可以被B继承过来,就不必重新开发。
2,特点:提高了可复用性,让类与类之间产生了关系,给多态提供了前提。
3,Java不直接支持多继承,因为:父类若出现相同方法名,不同方法体的情况,会产生不确定性。
4,当类与类之间存在所属关系时,运用继承。
5,子父类中成员变量的特点
a、当本类的成员和局部变量同名时用this区分 ; 当子父类中的成员变量同名时用super区分
b、this和super的用法很相似,但是this代表一个本类对象的引用,而super代表一个父类空间
c、在一个子类被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两个结合起来形成一个子类的对象。因此,继承使子类拥有父类所有的属性及方法,但是子类却不能访问父类对象中私有属性和方法。
6,子父类中成员函数的特点
a、覆盖:当子父类中出现成员函数一样(仅是方法体不同,其他相同)时,会运行子类的函数
只有在子类权限必须大于等于父类权限
静态只能覆盖静态,或被静态覆盖
7,子父类中构造函数的特点
class Fu { Fu() { //super(); show(); //return; } void show() { System.out.println("fu show"); } } class Zi extends Fu { int num=8; Zi() { //super(); //——》通过super初始化父类内容时,子类的成员变量并未显示初始化,等super() //父类初始化完毕后,才进行子类的成员变量显示初始化 System.out.println("zi cons run"); //return; } void show() { System.out.println("zi show ...."+num); } } class Test { public static void main(String[]args) { Zi z=new Zi(); z.show(); } } //运行结果 请解释为什么会出现这样的结果? zi show ....0 zi cons run zi show ....8
a、为什么子类实例化时要访问父类的构造函数?
子类继承父类,获取到了父类中内容(属性),所以在使用父类之前,要先看父类是如何对自己的内容初始化的
b、子类对象的实例化过程
1、JVM会读取指定的路径下的子类class文件,并加载至内存。如果在有父类的情况下,会先加载父类
2、在堆内存中开辟空间,分配地址
3、在对象空间中对对象中的属性进行默认初始化
4、调用构造函数进栈
5、在构造函数的第一行会先到调用父类中的构造函数进行初始化
6、父类进行初始化完毕后,在对子类的属性进行显示初始化
7、初始化完毕,将地址赋给引用变量
8,final关键字
a、继承的弊端:打破了封装性
b、final可修饰类、方法、变量
c、final修饰的类不可被继承
d、final修饰的方法不可被覆盖
e、final修饰的变量是一个常量,只能赋值一次
9,抽象类
abstract class M { abstract show (); } class A extends M { void show() { System.out.println("抽象类"); } } class Test { public static void main(String[]args) { A a=new A(); a.show(); } }
a、功能细节无法具体则使用抽象类
b、很显然,抽象类无法实例化
c、abstract修饰
d、抽象类必须由其子类覆盖了所有的抽象方法后,该子类才可以实例化,否则,子类也是抽象类。
e、关于抽象类的几个问题
1、抽象类中有构造函数吗? 有,用于子类对象进行初始化
2、抽象类可以不定义抽象方法? 可以,少见,目的:不让该类创建对象
3、抽象类关键字不可以和哪些关键字共存? private、static、final
4、抽象类和一般类的异同:抽象类描述事物信息有可能不足,可定义抽象方法、非抽象方法,不可被实例化
10,接口
a、当一个抽象类中的方法都是抽象时,可以将该抽象类用另一种形式定义和表示——接口
b、接口是一种规范,是一种规则,它只给出方法的样子,规定你要实现哪些方法,而不给出方法的实现,让接口的实现类去实现这些方法,但是对于不同的实现类来说,对方法的实现可以完全不同
c、接口中的常见成员:1、全局常量:public static final
2、抽象方法:public abstract 可简化不写修饰符,权限都是公开的
d、一个类可以实现多个接口使用关键字implements
e、一个接口可以继承多个接口使用关键字extends
f、一个类可以同时继承一个别的类,而且实现一个或多个接口,但是关键字extends要在前面
注意:面向对象设计的重点在于抽象,那Java 接口和Java 抽象类就有它存在的必然性了
四,多态
1,定义:某一类事物的多种存在形态,一种方法有多种实现版本
2,类的多态性表现为方法的多态和类的多态
a、方法的多态:包括方法的覆盖和重载,为一种功能提供多种实现
b、类型的多态:子类是一种父类类型
3,子类重定义从父类继承来的成员
a、重定义成员变量:隐藏父类成员变量
b、重定义成员方法:如果参数列表相同,则覆盖父类的方法,否则重载
4,类型的多态
a、子类通过继承方式扩充和发展了它的父类,继承约定了子类与父类之间存在的isA关系,子类是父类的一种特殊类型。例如:Student类——Person类——isA关系
b、子类对象包含了父类的所有成员变量,isA关系表现为继承具有“即是”性质:子类对象即是父类对象。反之不然,父类对象不是它的子类对象。使用对象运算符instanceof可以判断一个对象是否属于指定类及其子类。 如:new Person() instanceof Person
五、内部类
1、内部类的共性
(1)、内部类仍是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前冠以外部类的类名和$符号;
(2)、内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的 。
(3)、内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量 。
2、内部类的区分
(1)、成员内部类
class MemberInner { private int d = 1; private int a = 2; // 定义一个成员内部类 public class Inner { private int a = 8; public void doSomething() { // 直接访问外部类对象 System.out.println(d); // 直接访问a,则访问的是内部类里的a System.out.println(a); // 如何访问到外部类里的a呢? System.out.println(MemberInner.this.a); } } } public class Test { public static void main(String[] args) { // 创建成员内部类的对象 // 需要先创建外部类的实例 MemberInner.Inner inner = new MemberInner().new Inner(); inner.doSomething(); } }
成员内部类也是定义在另一个类中,但是定义时不用static修饰。成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量。成员内部类就像一个实例变量。它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以。
在外部类里面创建成员内部类的实例:
this.new Innerclass();
在外部类之外创建内部类的实例:
(new Outerclass()).new Innerclass();
在内部类里访问外部类的成员:
Outerclass.this.member
(2)、静态内部类
class StaticInner { private static int a = 4; // 静态内部类 public static class Inner { public void test() { // 静态内部类可以访问外部类的静态成员 // 并且它只能访问静态的 System.out.println(a); } } } public class Test { public static void main(String[] args) { StaticInner.Inner inner = new StaticInner.Inner(); inner.test(); } }
最简单的内部类形式。类定义时加上static关键字。不能和外部类有相同的名字。被编译成一个完全独立的.class文件,名称为OuterClass$InnerClass.class的形式。只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。生成静态内部类对象的方式为:
OuterClass.InnerClass inner = new OuterClass.InnerClass();
(3)、方法内部类
class LocalInner { int a = 1; public void doSomething() { int b = 2; final int c = 3; // 定义一个局部内部类 class Inner3 { public void test() { System.out.println("Hello World"); System.out.println(a); // 不可以访问非final的局部变量 // error: Cannot refer to a non-final variable b inside an inner // class defined in a different method // System.out.println(b); // 可以访问final变量 System.out.println(c); } } // 创建局部内部类的实例并调用方法 new Inner3().test(); } } public class LocalInnerClassTest { public static void main(String[] args) { // 创建外部类对象 LocalInner inner = new LocalInner(); // 调用外部类的方法 inner.doSomething(); } }
局部内部类定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。像局部变量一样,不能被public, protected, private和static修饰。只能访问方法中定义的final类型的局部变量。局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法。
(4)、匿名内部类
interface Product { public double getPrice(); public String getName(); } public class AnonymousTest { public void test(Product p) { System.out.println("购买了一个" + p.getName() + ",花掉了" + p.getPrice()); } public static void main(String[] args) { AnonymousTest ta = new AnonymousTest(); //调用test方法时,需要传入一个Product参数, //此处传入其匿名实现类的实例 ta.test(new Product() { public double getPrice() { return 567.8; } public String getName() { return "AGP显卡"; } }); } }
匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。匿名内部类隐式地继承了一个父类或者实现了一个接口。
六、包
1、包的特点
(1)、对类文件进行分类管理;
(2)、给类提供多层命名空间;
(3)、写在程序文件的第一行;
(4)、类名的全称是:包名.类;
(5)、包也是一种封装形式;
2、包的引用
(1)、每个类名前加上完整的包名
public static void main(String args[ ]){ java.util.Date now = new java.util.Date( ); System.out.println(now); } }
(2)、使用import语句导入包:一旦使用import之后,就不再需要给出完整的包名,注意是public类。
import java.util.Date; public class test {public static void main(String args[]) {Date now = new Date( ); System.out.println(now); } }
3、包的创建
用户可以根据编写的功能来把自己编写的类组织到包中,并可以把该包提供给其他人来使用包中的类,达到程序代码共享的目的。
packagecom.naviseek.canasta; public class employee{ private String name; private double salary; public employee(String n , double m){ name=n; salary=m; } public String getname(){ return name; } public double getsalary(){ return salary; } }
七、异常处理