(转)学习Java的相关笔记,新手受益匪浅!

第一章 java相关

大公司面试
重要:
数据结构的知识
-------------------------------
*掌握原理
-------------------------------
有价值的认证:
oracle dba认证
CCIE认证
。。。
含金量好的认证一百来说考试费很多
-------------------------------
ERP行业
ERP企业资源计划或称企业资源规划简称ERPEnterprise Resource Planning),由美国著名管理咨询公司Gartner Group Inc.1990年提出来的

共享软件行业
共享软件如:
魔法兔子
迅雷
。。。
-------------------------------
*不经常使用,使用的时候能够查到的知识:
 了解有这么回事,用的时候再去查
-------------------------------
*难得一用的知识:
 不必太专,用的时候再查
-------------------------------
*掌握业务逻辑
-------------------------------
查看共享目录:
IE浏览器地址栏上输入
\\ip地址,如:\\192.168.0.1
-------------------------------
*************
第一章 正式讲
*************
--------------------------------
1JAVA历史,了解即可,面试不会考
2JAVA学习过程  j2se->java web->j2ee
3JDK1.51.4多了范式
4、内存很重要,要弄透
5JAVA是解释型语言
6、一个JAVA文件中可以有多个类,但只能有一个public类,此类与文件名同名。
7path存放的是系统调用的可执行程序的目录
   classpath存放的是调用类的时候,相关联的类的目录

总结中:
1JAVA的垃圾收理机制,免除了内存管理的麻烦。需要开辟内存的时候可以直接开辟   ,不需要程序员来释放。

 

************
   
************
1,递归就是在方法内调用自己
2,println打印东西的时候先转换成字符串再打印
3,内存中有代码区,方法只有在执行的时候才会占用内存
4,分析程序从main方法开始分析
5,递归中,当执行一个递归函数时,每层递归都必须等待下一层递归返回具体值后,才能继续运行,向上层返回值。 (不懂的话,可以参看第二章_递归_2
--------------------------

 

第二章 基础知识

************
标识符
************
1,可以自己取名字的,都是标识符
2,对大小写敏感,长度无限制
3,中间不可以有空格
4,java标识符要"见名知意"

************
关键字
************
 
************
java常量
************

************
java变量
************
1,变量本质内存里的一块区域
2,不同的变量类型,在内存中分配的长度不一样
3,局部变量必须要有初值

~~~~~~~~~~~~~~~~~~~~~~~~
程序执行过程中的内存管理
~~~~~~~~~~~~~~~~~~~~~~~~
1,code segment 存放代码
2,data segment 存放静态变量,字符串常量
3,stack (存放局部变量
4,heap (存放new出来的东西;动态申请内存

~~~~~~~~
局部变量
~~~~~~~~
1,在方法体内部定义的变量
2,函数的参数

~~~~~~~~
成员变量
~~~~~~~~
在方法体外,类内

~~~~~~~~~~~~
变量的作用域
~~~~~~~~~~~~
凡在{}内定义的变量,出了{}就不起作用了

************
java数据类型
************
1,逻辑型 Boolean 只允许取 truefalse
 Boolean bl;
  bl = true;
2,字符型char
 char eChar = 'a';
 char eChar = '';
  采用Unicode编码,每个字符占两个字节,十六进制编码
  
  转义字符'\'来将其后的字符转变为其他的含义
  char c2 = '\n';  //'\n'代表换行
3,整数类型byte(1字节) short(2字节) int(4字节) long (8字节)
 *long l = 8888L L必须加,不然会被认为是int类型)
4,浮点类型 float(4字节)  double(8字节)
 *float f = 12.3f(当所赋的值是小数的时候f必须加,不然会被认为是
 double类型)浮点说在计算机中是离散的,是有一定误差的。float精确
 到小数点后7位,double精确到小数点后15
    
************
数据类型转换
************
1,byte short char之间不会互相转换,他们在计算的时候首先转换成int类型
2,容量(所能表示的数的多少)大的数据类型转换为容量小的数据类型时,要加
  上强制转换符,但可能造成数据溢出或者精度降低
 *double d = 10.1;d转换为int类型:
  int i = (int)d;

  在一个数据类型转换为比他位数少的类型时,会将多的部分去掉,余下的数 
  是多少就是多少。
  比如,int类型为4位,byte类型为1位,当int类型转换为byte类型时,会去
  3位,余下的40/1表示什么,那么转换后的值就是什么。
  
  但对float不能如此的转换为double类型,因为在内存中对于浮点数的存储不
  同于整数类型的存储。这也是声明float类型时,给变量赋值为小数时时必须
  f。否则会默认为double类型,然而double类型无法转换为float类型,所
  以会出错
************
程序格式
************
1,大括号对齐。即左右两个大括号所在的行的左部要一齐,而不是指括号对齐
2,程序块之间要加空行
3,运算符两侧加空格
 *原则:让别人看的更清楚
************
运算符
************
1,++放在后面,先取值后计算
  int i = (i2++); //先把i2的值赋值给i,然后i2++
  
  ++放在前面,先计算后取值
  
  --同理
2,逻辑运算符中 & | 比如 a&b a|b 需要计算a b真值然后给出表达式 a&b a|b的真值
  而 && || 比如a&&b a||b叫做短路与,短路或。如对于a&&b a = false 则不计算
  b给出表达式的真值。  a||b也一样,如果a确定为true则,无需计算b直接给出表达
  式为true
3,"+"可以做字符串连接 如:String s = "hello" + "world";
4,"+"运算符两侧的操作数中只要有一个是字符串(String)类型,系统会自动将一个操
  作数转换为字符串然后再进行连接。
  int c = 12;
  System.out.println("c = " + c); //由于"c = "为字符串,所以系统会先将后面的
  c先转换成字符串再连接,12转换成字符串还是12
 *当使用println()进行打印的时候,无论任何类型,都在自动转化为字符串,再打印。
  (已经是第二次说明此问题)
  println(c);时,会先将c转化成字符串再打印
************
语句
************
1,for循环中for(语句1;语句2;语句3){语句4}
  执行顺序:
  语句1 -〉 语句2(若语句2为真)-〉语句4 -〉语句3 -
            语句2(若语句2为真)-〉语句4 -〉语句3 -
            语句2(若语句2为假)-〉结束for语句
2,如何分析程序:
  分析内存:
  每遇到一个变量就在内存中画出来
  当变量的值有改动的时候,在内存中显示出来
3,do{}while(); 记住后面要有个";"
4,continue终止本次循环,continue下的语句不运行,而是直接进行下一次循环
  语法与break一样  如:if(i==5) continue; 
************
方法
************
1,方法的作用:
  增强代码的复用性
2,形参数据类型
  实参数据

 

 

面向对象的思想

 

**************
面向对象的思想
**************
1,将与问题有关的对象和他们之间的联系抽象出来
  而不是考虑第一步要做什么,第二步要做什么。
2,用面向对象的思想来思考问题的步骤
  第一步:
  考虑这个问题域里有哪些类,哪些对象
  第二步:
  这些类,这些对象有哪些属性
  第三步:
  考虑他们之间的关系,他们应该有哪些方法
3,合适的方法应该出现在合适的类里
4,跟业务逻辑无关的方法不需要出现在类中
5,Java外事万物皆对象
******************
面向对象的基本概念
******************
1,对象的属性,即成员变量,在声明的时候可以初始化,如果不初始化java默认初始化Boolean类型为false 引用类型为null 其他为或 0.0
2,引用类型(8种基本类型之外的类型)占两块内存
3,java中的对象是通过引用对其操作的
  比如:Dog d = new Dog("Tom");
  Dog d时,d要在内存中开辟一个空间,初始为null
  new后,会在堆中动态的开辟一个内存来存放Tom,此时d的值为Tom
  但不能直接访问Tom,需要通过d来访问,类似C++语言中的指针
4,引用:
  一小块内存指向一大块内存
  使用方法:对象.成员变量
            对象.方法
  这里的"."相当于C++里的->
5,同一个类的不同对象在内存中有不同的空间,但共用方法和属性
6,构造方法:
  名字与类名一样,无返回值。与new一起使用创建一个新对象
  public class Person {
     int id;
     int age = 20;    
     //Person的构造方法
     Person(int _id,int _age) {
 id = _id;
 age = _age;
     }
  }
  
  Person p = new Person(1,40); //此处的Person(1,40)是类Person的构造方法

  当不写构造方法的时候,系统默认创建一个形如:类名(){} 这样的构造方法。
  但当自己写了构造方法后,当创建类的时候,就必须使用自己创建的构造方法了。
7,约定俗成的命名规则:
  类名,首字母大写
  方法名、变量名,小写
  运用驼峰标示 

 

 

第三章 java学习之类的学习

 

************
方法
************
1,重载:
  方法名一样参数不一样
  在调用的时候会根据参数的不同调用不同的方法

2,构造方法也可以重载

3,确定方法的步骤
  第一步确定方法的名字
  第二步确定方法的参数
  第三步确定方法的返回值
************
this关键字
************
1,this可以看作是一个变量,值是当前对象的引用
  
2,用来处理方法中,成员变量和参数重名的情
************
static关键字
************
1,static 声明的成员变量为静态成员变量,它为该类的公用变量

2,不需要new对象即可使用 
  如:类名.静态成员变量 = 100; 即可
  对象也可以使用 
  如:对象.静态成员变量 = 200;

3,可以用来计数

4,static方法中不能访问非static成员变量
**************
package,import
**************
1,包名:
  公司域名倒过来写

2,package语句必须位于java代码的第一行

3,package中用.来说明目录的层次
  如:package com.sxt
      则该文件中所有的类位于.\com\sxt目录下 "." 为当前目录

4,使用import引用一个包里的类
  如:import com.sxt.MyClass;  //引入com.sxt里的MyClass
      import java.util.*; //引入java.util包里所有的类

5,访问位于同一个包中的类不需要import引用包,可以直接使用

6,执行一个类,必须包括其所在的包名
  (使用命令提示符执行class文件时)

7,java.lang使用时可以不引用,其他的包使用时需要引用

8,如何打jar包:
  cd 到 要打包的类的目录
  jar -cvf xx.jar(jar包的名字) xx.xx(要打包的类的名字和后缀
  *.*代表所有的类)
  可以把其所在的路径放到classpath里便于调用里面的类
**************
继承和权限控制
**************
1,使用extends关键字实现类的继承
  通过继承,自类自动拥有了基类(父类)的所有属性和方法
  私有的属性也会被继承,但是无法访问,即无法修改和使用其属性
  写法:
  public(可选项) class 子类名 extends 基类名 {}

2,java不允许多重继承

3,权限控制     范围
  private      类内
  default      类内  包内       (就是class前什么都不写)
  protected    类内  包内  子类
  public       任何地方

  只有defaultpublic可以修饰class
  
4,方法重写
  在子类中可以根据需要对从基类中继承的来的方法进行重写
  
  重写方法必须和被重写方法具有相同的方法名,参数列表,返回类型

  重写方法不能使用比被重写方法更严格的访问权限

5,super用来引用基类的成分,相当于在一个父类的对象,且不需要声明
  可以直接引用
  如:
  子类在重写父类的方法f()时,可以
  public void f() {
 super.f();   //将父类f()这个方法引用进来
        value = 200; //再写自己的方法
                     //要注意的是,如果父类里有value,子类的value
                     //和它占用不同的内存,简单来说,他们不是一个
        //value
  }
        
6,子类的构造方法中必须调用其父类的构造方法,即在子类构造方法中,应
  使用 super(子类构造函数的形参),且必须写在构造方法的第一行
  如:
 public class Worker extends Person implements CarePet {
 //子类构造函数
 Worker(String name) {
  super(name);
 }
 }


  如果子类的构造方法没有显示的调用父类的构造方法,则默认调用无参的
  构造方法

  this(参数列表调用自己的其他构造方法

7,Object
  是所有Java类的基类,可以重写其中的方法。
  比如:Object类里的toString()方法,与字符串作连接或者直接打印出来的时
  候,转换成字符串。这个方法经常被重写。
  正常情况下,无需写出,会默认执行

  equals()方法也经常需要重写,在比较类的对象a,b是否相同的时候,equals()
  默认认为,传进来的对象的引用和调用它的对象的引用所指向的是同一对象才
  会返回true

**************
对象转型
**************  
1,一个基类的引用可以指向其子类
  比如:
  class Person {}
  class Son extends Person {
 private myLove;
 public void mine(){}; //子类自己的方法
  }
  
  public class Test {
 public static void main(String[] args) {
  Person p = new Person();
  p = new Son();   //一个基类的引用指向其子类
       //但其不可以访问子类自己的方法mine()
     //也不可以访问子类自己属性myLove
     //此时p还被认为是Person类的一个对象
     //需要强制转换才能成为为Son类型
 }
  }

2,可以使用instanceof来判断一个引用是否为一个类
  比如:
  p instanceof Person
  这个式子返回一个true 或者 false 这里显然是true

3,可以通过强制转换,将基类转换成子类
  比如:
  Son s1 = (Son)p; //p强制转换成Son类型
  同级的类,无法转换
  比如:猫类不能转换成狗类

**********************
多态:迟绑定,动态绑定 
**********************  
1,增强了可扩展性

2,多态的3个必要条件
  1,要有继承
  2,要有重写
  3,父类引用指向子类对象

3,在执行的时候,根据new出来的对象来动态得调用对应
  的被重写的方法
  比如
  class Animal {
 protected String name;
 
 protected void enjoy() {
  System.out.println("开心");
 }
  }

  class Cat extends Animal {
 private String eyesColor;
 
 public void enjoy()
  }
  
****
抽象
****
1,abstract来修饰的方法就是抽象方法,只有声明没有实现
  如:
 public abstract void enjoy();

  子类中需要对抽象方法进行重写
  
  当一个类中有抽象方法的时候,这个类也必须被声明为抽象类
  :
  abstract class Animal {
 ......
  }
  抽象类必须被继承
  抽象类无法new出对象,即不能实例化

***********
final关键字
***********
1,final修饰的变量,一旦被赋值就不能再改变
  如:
  public void m(final int j) {
 j = 9; //这个是错误的,在调用这个方法的时候,j就被 
               //赋值,方法里面不能改变j的值
  }

2,final的方法不能被重写

3,final的类不能被继承


***************
interface关键字
***************
1,接口是一种特殊的抽象类,只包含常量和方法的声明,而没有变量
  和方法的实现
  如:
  public interface Runner {
  public static final int id = 1; //成员变量默认为public static final
                                  //即,即使不标明,也是这种类型,而且
                                  //只能是这种类型
  public void start();            //默认为public
  public void run();
  }

  public interface Painter {}

2,一个类可以实现多个接口
  类继承接口的形式:
  class Student implements Runner {}
  
  class Teather implements Runner,Painter {}

3,接口可以继承其他的接口,并添加新的属性和方法

 

 

第四章 异常处理

 

***********
异常处理
***********
1,异常exception
  程序运行期间出现的错误

  try {
 System.out.printlun(2/0);
  } catch (ArithmeticException ae) {
 System.out.println("系统出错");
 ae.printStackTrace();  //打印出错的地方和原因  
  }

2,方法抛出异常的写法
  //声名该方法可能抛出的异常
 //throws 抛出自己无法处理的异常
  public void someMethod() throws SomeException { 
 if(someCondition()) {
  //构造并抛出异常对象
  throw new SomeException("error");
        }
  }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  //异常可以处理
  try {
 someMethod();
  } catch(SomeException e) {
  //异常处理代码
  }
  
  一个try可以有多个catch,但必须先catch小的,catch范围大的
  :
    try {
 someMethod();
  } catch(SomeException e) {
  //异常处理代码
  } catch(SomeException2 e) {
  //异常处理代码
  }finally {
 //异常捕获后,这里的语句可以继续执行
 //异常没有捕获,也会被执行
  }
  通常在finally语句中可以进行资源清除的工作
  如:
 关闭打开的文件
 删除临时文件

3,Throwable为异常类的基类
  其子类Error Exception
  其中Error 是无法处理的异常,叫做错误
  Exception 是可以处理的异常

  RuntimeException 常出的异常 是Exception的子类
  此类错误可以不catch

* 5个关键字 try catch throw throws finally
 
**************
使用自定义异常
**************
1,通过集成java.lang.Exception类声明自己的异常类
  如:
 class MyException extends Exception {
 private int id;  //id为异常的序号
 
 public MyException(String message,int id) {
  super(message);
  this.id = id;
 }
 public int getId() {
  return id;
 }
  }

2,重写方法需要抛出与原方法所抛出异常类型一致异常或不抛异常
  如:
 class A {
 public void method() throws IOException {}
  }
  //下面这个是错的,因为抛出的异常与其父类的类型不一致
  class B1 extends A {
 public void method() throws FileNotFoundException {}
  }
  //下面这3个是正确的,因为
  B2抛出的异常是其父类抛出的异常的父类
  B3没有抛出异常
  B4抛出的异常和其父类抛出的异常一样
  class B2 extends A {
 public void method() throws Exception {}
  }

  class B3 extends A {
 public void method() {}
  }

  class B4 extends A {
 public void method() throws IOException {}
  }

 

 

第五章 数组

 

************
1维数组
************
1,声明方式
  type var[]; 或 type[] var;

2,Java中使用new创建数组对象
  数组名 = new 数组元素的类型[元素个数]
  如:
  int[] s;
  s = new int[5];
  s[0] = new Date(1,4,5);

3,静态初始化数组
  int a[] = {3,9,8};

4,s.length的值为数组s的长度
  length为一个属性,后面不要加()

5,类型转换
  public static void main(String[] args) {
  //String类型转换为double类型
  double d1 = Double.parseDouble(args[0]);
  }
  
6,退出程序
  System.exit(-1); //非正常退出
  System.extt(0);  //正常退出

************
2维数组
************
1,java中多维数组的声明和初始化,应按从左到右的顺序进行
  
  int a[][] = new int[3][];
  a[0] = new int[2];
  a[1] = new int[4];
  a[2] = new int[3];

  int a[][] = new int[][3];  // 这个是错的

2,初始化数组
  静态初始化
  int a[][] = {{1,2},{3,4},{5,6}};
  int a[3][2] = {{1,2},{3,4},{5,6}};  //这个是错的

  动态初始化
  int a[][] = new int[3][2];
  int b[][] = new int[3][];

  b[0] = new int[2];
  b[1] = new int[4];
  b[2] = new int[3];
3,arraycopy(Object src,int srcPos,Object dest,int destPos,int length)

  用于从数组src从第srcPos项开始的length个元素拷贝到数组dest从第destPos
  个开始的length个位置
  
  注意,这里仅仅是拷贝引用,实际的数值还在src数组所在的内存中,所以修改
  srcdest两个数组的中拷贝的任何一个值,另一个的值也随之改变

 

第六章 常用类

 

本章复习重点看练习代码,笔记太概括,不全。

***********
常用类
***********
1,String
  有很多常用的方法,详见代码UsuallyClass_String包的代码
  如:
  valueOf()可以将其他类型转换为字符串类型,默认会调用toString()方法,
  如果我们从写toString方法则调用我们重写的这个

  不可变字符序列,即一旦初始化了String的引用,那么它所指向的内存的大小
  就无法改变,若要改变引用的其值,只能另辟空间,将引用指向新的空间

2,StringBuffer
  相对于String类,是可变的类。可以对字符串进行,插入,删除部分字符

3,基本数据类型包装类

  将基础类型包装成对象
  如:
  public static Interger valueOf(String s) throws NumberFormatException

  返回Integer对象,其中封装的整型数为字符串s所表示

4,Math
  max(double a,double b)
  min(double a,double b)
  random() 0.01.0的随即数
  round()四舍五入到long类型,小数点后一位四舍五入

5,File类 java.io.File类代表系统文件名(路径和文件名)
  public static final String separator 路径分隔符,是静态的

6,枚举类型java.lang.Enum
  使用enum关键字
  只能取规定的值里面的一个

  public enum MyColor {red,green,blue};

  MyColor m = MyColor.red;
  MyColor n = 0; //是错的,只能是red green blue 里的一个

要学会并经常查API文档

 

 

第七章 容器

 

************
容器
************
     Collection interface                        Mapinterface
 _______|    |_____                                     |
|                           |                                 HashMap
Setinterface》 Listinterface》 
|                        ____| |___
HashSet              |              |
                 LinkedList  ArrayList

Set 的数据对象:无序的,不能重复的
List的数据对象:有序的,可以重复的

所谓重复 可以equals


Map  一对一对的装: Key 和 value

1,容器里面装的必须是Object,是对象,不可以是基础类型。

2,同一个容器可以放不同类型的对象

3,容器类对象在调用remove contains需要比较对象是否相等,这会涉及到对对象
  类型的equals方法和hashCode方法。
  对于自定义的类,需要重写equalshashCode方法以实现自定义的对象相等规则

  相同的对象有相同的hashCode。当传入的对象是key的时候,需要调用hashCode方法

4,重写equals应该重写hashCode方法

面向对象的编成,重设计。

************
Iterator接口
************
1,所有实现了Collection接口的类都有一个Iterator方法,用来返回一个实现了
  Iterator接口的对象

  Iterator对象称作迭代器,用以实现对容器内元素的遍历操作

  假设c为一个类的对象
  Iterator i = c.iterator();
  此时i是一个指针 i.next() 这个是容器里存储的对象。初始i是在容器内第
  一个对象之前,所以i.next()就是第一个对象
  i.hasNext()是判断i指向的对象是否为空
 

************
增强的for循环:
int[] array = {1, 2, 3, 4, 5}
for(int i : array) {
 System.out.println(i);
}

好处在于语法简便
但只能用于输出数组内容
************

************
Set接口
************

1,在是用HashSetadd()方法时,重复添加无效
  如:
  HashSet s = new HashSet();
 s.add("a");
  s.add("b");

  s.add("a"); //无效,即s内只会有一个"a"
 
************
List接口
************

1,Object set(int index, Object element) 返回值是被修改前的对象

2,要使用Collections.sort()方法必须继承Comparable接口,实现里面的
  public int compareTo(Object o) 这个方法
  
  里面有好多方法

****************
如何选择数据结构
****************
1,Array读快改慢
  Linked改快读慢
  Hash两者之间

************
Map接口
************
1,实现类HashMap TreeMap

2,Map类中存储的键值不能重复,此类的比较,是比较hashcode,hashcode一样
  就一样


Auto-boxing/unboxing
在合适的时机自动打包,解包

自动将基础类型转换成对象类型
自动将对象类型转换成基础类型

************
泛型:
************
所谓泛型:
容器类后面的<>里面放上容器中所存储的类名

1,增强程序的可读性和稳定性

 

 

第八章 流

 

************

************
1,                字节流(每次8)         字符流(每次16)  一个汉字为16
   输入流        InputStream              Reader
   输出流        OutputStream       Writer

输入,输出以程序的角度

节点流: 直接接在数据源上的流 
处理流: 包到别的流上的流

2,良好的编成方式
  先写flush();再写close();

************
节点流
************


************
缓冲流
************
带缓冲区的流

************
转换流
************
InputStreamReader
OutputStreamWriter

************
数据流
************

************
打印流
************
PrintWriter PrintStream 自己有flush();功能

************
Object
************
Object直接转换成字节流,输出到某个地方,叫做序列化

Serializable接口  序列化接口  叫做标记性的接口

所谓标记性的接口  未定义任何方法的接口

任何可以序列化的类都需要实现Serializable接口

transient透明的 用来修饰类中的成员变量  起作用是在序列化的时候
不考虑它修饰的变量的值,安默认的值算


externalizable接口 继承于Serializable,内含两个方法
实现了自己控制自己的序列化过程,补偿使用,也不建议是用
************
流的总结
************
本章介绍了很多流,整理如下

IputStream/OutputStream  字节流
Reader/Writer   字符流

*****下面两种是直接与数据源相连的流*****
对文件的读写
参数是文件名
FileInputStream/FileOutputStream
FileReader/FileWriter

以字节数组的形式读取,可以实现不经文件直接从键盘读取
参数是byte[]类型
ByteArrayInputStream/ByteArrayOutputStream


*****下面的流是套在上面两个流外面的流*****
带缓冲区的流,通常是套在别的流之外。
BufferedInputStream/BufferedOutputStream  参数分别是InputStream,OutputStream类型
BufferedReader/BufferedWriter    参数分别是Reader,Writer类型

转换流,用于将字节流转换成字符流
InputStreamReader/OutputStreamWriter 参数分别是InputStream,OutputStream类型

数据流,提供了可以读取基础类型的数据的方法
DataInputStream/DataOutputStream 参数分别是InputStream,OutputStream类型


打印流(这个流比较特殊,参数很多:File String OutputStream Writer都可以)
PrintStream/PrintWriter

对象流,直接读取对象类型的数据
ObjectInputStream/ObjectOutputStream  参数分别是InputStream,OutputStream类型

 

第九章 线程

 

************
线程
************
1,线程:
 进程是个静态的概念,在机器上运行的是线程.
 
 线程是程序中执行的不同路径

 一个CPU一个时间点,只能支持一个线程

2,线程实现:
  详见WhatIsThread

3,线程实现能使用Runnable接口就不要从Thread继承

4,关于线程的一些方法,详见代码 (在character9包里的代码)

************
线程同步
************
1,synchronized(this) {
  //some...
  }
  执行方法过程中锁定当前对象

2,死锁:锁定了多个对象而产生的问题
 如:
 这个方法,必须要锁定对象a和对象b才能完成,而一个对象A先锁定了
 对象a,同时对象B先锁定了对象b,A需要锁定b才能结束方法的调用
 B也需要锁定a才能结束方法的调用。这样A,B都无法完成方法的调用
 这就叫做死锁
  
  解决方法
  1,只锁一个对象
  2,锁的范围加大
     比如:锁定ab的父对象,好比为了不死锁,不对两间
           屋子进行锁定,而是直接锁定房子
  3,其他。。。
************
生产者消费者
************
1,wait();
  锁定一个对象后,当前的线程停住
  wait的时候,锁不归当前对象所有

2,notify()wait()一一对应
  叫醒正在等待的线程

 

 

 

第十一章 GUi

 

************
图形界面GUI
************
1,Component
  Java的图形用户界面的最基本组成部分
  比如一个标签,一个按钮等
  
2,一般的Component对象不能独立显示出来,必须将其放在      Container对象中才可以显示出来

3,ContainerComponent子类,其对象可以使用add()方法
  向其中添加Component元素

4,有两种Container
  Window: 其对象表示自由停泊的顶级窗口

  Panel: 其对象可容纳其它Component对象,但不能独立存在。
  必须被添加到其他Container

************
window
************

1,FrameWindow的子类,有Frame或其子类创建的一个对象作为
  一个窗体
  Frame的一些方法
  Frame(String s)创建标题栏为s的窗口
  其他参阅api文档

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
setResizable(boolean b)设置是否可以调整大小
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2,Panel
  Panel放在Frame中,其他方法和Frame基本一样

************
布局管理器
************
自动提供布局管理
设置布局管理器后,会覆盖自己设计的布局

Awt提供了5
1,FlowLayout
  对组件逐行定位,行内从左到右,一行排满后换行

  不改变组件的大小,按组件原有尺寸显示组件,可设置不同
  组件间的间距,行距以及对齐方式。默认对齐方式是第一行
  居中
  Panel类的默认管理器
2,BorderLayout
  划分成东西南北中五个区域,添加组件的时候,默认会加到
  中区域,每个区域只能添加一个组件
  
  Frame类的默认管理器

3,GridLayout
  划分成表格
  GridLayout(m,n) 划分成m行 n

4,GardLayout

5,GridBagLayout


************
事件监听
************
1,过程:
             发生了某件事                           接到对象后监听器进行某种处理
  事件原对象     -->       向监听器传送某种事件对象             -->              

                                   注 册
  实现了某种监听其接口的类的对象    -->  事件原对象

************
TextField
************

************
内部类
************
 类内的类

1,可以直接访问类内的成员变量和方法
2,在不需要其他类访问时用
 


************
Graphics
************
每个Component都有一个paint(Graphics g)用于实现绘图的目的,每次重画(
每次重新打开窗口,比如最小化后恢复)Component时都自动调用paint方法

g相当于一支画笔,每次画图要是用它来画,画之前要设置它的颜色

 

绘制图形的部分待续

***********

键盘和鼠标的事件,参阅代码

***********

 

 

 

附录1: 

JDK如何配置 和 为什么要这样配置 附加 HelloWorld小程序的简单解释

 

********************************
JDK环境变量的配置:
********************************
计算机右键->“属性”-高级-〉环境变量-〉新建(用户的变量、系统变量均可。但用户情况建议适用用户变量)-〉在点击新建后出现的对话框中的变量名

1,填写classpath(大小写没有关系)变量值填写JDK安装文件的路径。比如JDK安装在C:\java\jdk6下,可以在变量值下输入C:\java;. 其中.代表当前路径

2,填写path(大小写没有关系)变量值填写JDK安装文件的路径+\bin。比如JDK安装在C:\java\jdk6下,可以在变量值下输入C:\java\jdk6\bin

查看环境变量的另一种方法:在命令行窗口里输入"echo %classpath%" (注意没有"",以下同理)就可以查看classpath里的值了。

相信很多人和我曾经一样,只知道如何配置但不知道为什么要这样配置,所谓知其然更要知其所以然,所以这里说明一下为何要如此的配置:

1,在windows下运行一个可执行文件默认会在当前目录下查找此文件,当当前目录下没有的时候,会到path里面寻找,如果都没有那么就会提示无法执行了。而配置path就是因为要用到bin这个目录下的java.exe javac.exe这个两个可执行文件

2,比如有个类叫HelloWorld.class,在运行命令 "java HelloWorld"的时候,系统会通过classpath里面的路径来寻找HelloWorld.class这个文件,没有的话就无法运行。默认应该也会在当前目录下先搜索,但是有时也找不到。这个就是人品问题啦,所以以防万一,配置的时候把当前路径,就是"."也要加上

可以写一个简单的JAVA文件测试环境变量配置是否正确
F盘下建一个java文件夹,里面建立一个HelloWorld.txt然后在里面写上
public class HelloWorld {
 public static void main(String[] args) {
  System.out.println("hello world");
 }
}
然后保存,最后将后缀名txt改为java,出现提示框点击确定即可

然后打开命令提示符,可以按windows键(就是windows图标那个键)+R 在弹出的运行对话框里输入 cmd 然后在出现的 命令提示符中输入f:然后点击确定,进入f盘,然后输入cd f:\java确定,进入java文件夹下。继续输入javac HelloWorld.java点确定。之后会看到java文件夹下出现了一个HelloWorld.class文件,继续输入java HelloWorld点击确定,如果出现hello world。说明配置成功。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

相信有好多初学者和我一个月前一样也不懂这个最简单的程序的含义,简单解释一下

//这个名字"HelloWorld"必须要和你你的文件名一致,也就是说文件名也必须是HelloWorld.java

public class HelloWorld {

/*

这里的是固定写法,一个词都不能少,这里唯一可随便你写的是args这个不过是个变量的名字,改称abc都无所谓,不过大部分人都写成args所以大家随大流吧。

*/

/*

另外main函数是有参数的(String[] args) ,也就是String类型的数组,那么如何给main穿参数呢?很简单,比如我想传个helloworld放在这个数组中,只要在命令行下输入 java HelloWorld helloworld 就可以了,为了验证你确实传进去了,我们再加一行代码System.out.println(args[0]); 这样打印结果应该是两个,一个是首字母大写的,一个是你传进去的那个。

*/
 public static void main(String[] args){
  System.out.println("hello world");

  System.out.println(args[0]);
 }
}

好了解释完毕,各位学习Java快乐

 

附录2

为什么会出现 java.util.ConcurrentModificationException 异常?

 

Map或者Collection的时候,不要用它们的API直接修改集合的内容(否则会出现 java.util.ConcurrentModificationException 异常),如果要修改可以用Iteratorremove()方法,例如: 
________________________________________________

public void setReparation( Reparation reparation ) {
        for (Iterator it = this.reparations.iterator();it.hasNext();){    //reparationsCollection
            Reparation repa = (Reparation)it.next();
            if (repa.getId() == reparation.getId()){
                this.reparations.remove(repa);
                this.reparations.add(reparation);
            }
        }
   }

_________________________________________________

如上写会在运行期报ConcurrentModificationException,可以如下修改:

_________________________________________________

    public void setReparation( Reparation reparation ) {
        boolean flag = false;
        for (Iterator it = this.reparations.iterator();it.hasNext();){    //reparationsCollection
            Reparation repa = (Reparation)it.next();
            if (repa.getId() == reparation.getId()){
                it.remove(); 
                flag = true;
                break;
            }
        }
        if(flag){
          this.reparations.add(reparation);
        }
    }

__________________________________________________________

 

转:ConcurrentModificationException主要原因及处理方法
当使用 fail-fast iterator 对 Collection 或 Map 进行迭代操作过程中尝试直接修改 Collection / Map 的内容时,即使是在单线程下运行,   java.util.ConcurrentModificationException 异常也将被抛出。

  Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。

  所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。

  有意思的是如果你的 Collection / Map 对象实际只有一个元素的时候, ConcurrentModificationException 异常并不会被抛出。这也就是为什么在 javadoc 里面指出: it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.

 

 

 

 

附录3

如何将对象存到文件中去(转载)

package test1;

//我也来凑个热闹,建议将数据封装在一个对象中
//这个例子是将一些数据封装在Person对象中
//:SerializableTest.java

import java.io.*;
import java.util.ArrayList;

public class SerializableTest {
 public static void main(String[] args) throws Exception {
  // 保存对象的文件,这个要根据自己需要重新调整的,我这个是在Linux下的目录结构
  File f = new File("f:/person.dat");
  // 创建一个集合类,用于存放person对象
  ArrayList ps = new ArrayList();
  // 10person对象放入到集合中
  for (int i = 0; i < 10; i++) {
   ps.add(new Person("" + i, i));
  }

  // 因为ArrayList类已实现了序列化,所以可以将ArrayListps存入文件
  // 也就是说,现在保存的是一个集合,里边的内容是Person对象
  IO.save(ps, f);

  // 从文件中将这个集合读取出来
  Object o = IO.load(f);
  ArrayList list = (ArrayList) o;

  // 打印这个集合中的内容
  for (int i = 0; i < 10; i++) {
   System.out.println(list.get(i));
  }
 }
}

class IO {
 // 保存对象到文件
 static void save(Object obj, File f) throws Exception {
  ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));
  oos.writeObject(obj);
  oos.flush();
  oos.close();
 }

 // 从文件读取对象
 static Object load(File f) throws Exception {
  ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
  Object obj = ois.readObject();
  ois.close();
  return obj;
 }
}

// 要想Person能以对象的形式保存到文件,Person类必须实现序列化:Serializable
class Person implements Serializable {
 private static final long serialVersionUID = 6213933727640755594L;
 private String name;
 private int id;

 Person(String n, int i) {
  name = n;
  id = i;
 }

 public String getName() {
  return name;
 }

 public int getId() {
  return id;
 }

 public String toString() {
  return "name:" + name + "  id:" + id;
 }
}

 

转载于:https://www.cnblogs.com/Aiken/archive/2012/11/30/2795814.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值