leochiang

BlogJava 联系 聚合 管理
  21 Posts :: 0 Stories :: 1 Comments :: 0 Trackbacks

#

      http://lavasoft.blog.51cto.com/62575/18920/ 


      Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.ThrowableThrowable下面又派生了两个子类:ErrorExceptionError 表示应用程序本身无法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题。Exception表示程序还能够克服和恢复的问题,其中又分为系统异常和普通异常,系统异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉,例如,数组脚本越界(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException)、类转换异常(ClassCastException);普通异常是运行环境的变化或异常所导致的问题,是用户能够克服的问题,例如,网络断线,硬盘空间不够,发生这样的异常后,程序不应该死掉。

      java为系统异常和普通异常提供了不同的解决方案,编译器强制普通异常必须try..catch处理或用throws声明继续抛给上层调用方法处理,所以普通异常也称为checked异常,而系统异常可以处理也可以不处理,所以,编译器不强制用try..catch处理或用throws声明,所以系统异常也称为unchecked异常。

      Java异常处理通过5个关键字try、catch、throw、throws、finally进行管理。基本过程是用try语句块包住要监视的语句,如果在try语句块内出现异常,则异常会被抛出,你的代码在catch语句块中可以捕获到这个异常并做处理;还有以部分系统生成的异常在Java运行时自动抛出。你也可以通过throws关键字在方法上声明该方法要抛出异常,然后在方法内部通过throw抛出异常对象。finally语句块会在方法执行return之前执行,一般结构如下:

 try{
  程序代码
 }catch(异常类型1 异常的变量名1){
  程序代码
 }catch(异常类型2 异常的变量名2){
  程序代码
 }finally{
  程序代码
 }
        catch语句可以有多个,用来匹配多个异常,匹配上多个中一个后,执行catch语句块时候仅仅执行匹配上的异常。catch的类型是Java语言中定义的或者程序员自己定义的,表示代码抛出异常的类型,异常的变量名表示抛出异常的对象的引用,如果catch捕获并匹配上了该异常,那么就可以直接用这个异常变量名,此时该异常变量名指向所匹配的异常,并且在catch代码块中可以直接引用。这一点非常非常的特殊和重要!
        Java异常处理的目的是提高程序的健壮性,你可以在catch和finally代码块中给程序一个修正机会,使得程序不因异常而终止或者流程发生以外的改变。同时,通过获取Java异常信息,也为程序的开发维护提供了方便,一般通过异常信息就很快就能找到出现异常的问题(代码)所在。
        Java异常处理是Java语言的一大特色,也是个难点,掌握异常处理可以让写的代码更健壮和易于维护。

下面是这几个类的层次图:
java.lang.Object
  java.lang.Throwable
      java.lang.Exception
       java.lang.RuntimeException
   java.lang.Error
       java.lang.ThreadDeath
 
下面四个类的介绍来自java api 文档。
 
1、Throwable
        Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。
两个子类的实例,Error 和 Exception,通常用于指示发生了异常情况。通常,这些实例是在异常情况的上下文中新近创建的,因此包含了相关的信息(比如堆栈跟踪数据)。
 
2、Exception
        Exception 类及其子类是 Throwable 的一种形式,它指出了合理的应用程序想要捕获的条件,表示程序本身可以处理的异常。
 
3、Error
        Error 是 Throwable 的子类,表示仅靠程序本身无法恢复的严重错误,用于指示合理的应用程序不应该试图捕获的严重问题。
在执行该方法期间,无需在方法中通过throws声明可能抛出但没有捕获的 Error 的任何子类,因为Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用try...catch语句捕获它,也没有用throws字句声明抛出它,还是会编译通过。
 
4、RuntimeException
        RuntimeException 是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用try...catch语句捕获它,也没有用throws字句声明抛出它,还是会编译通过,这种异常可以通过改进代码实现来避免。
 
5、ThreadDeath
        调用 Thread 类中带有零参数的 stop 方法时,受害线程将抛出一个 ThreadDeath 实例。
        仅当应用程序在被异步终止后必须清除时才应该捕获这个类的实例。如果 ThreadDeath 被一个方法捕获,那么将它重新抛出非常重要,因为这样才能让该线程真正终止。
如果没有捕获 ThreadDeath,则顶级错误处理程序不会输出消息。
        虽然 ThreadDeath 类是“正常出现”的,但它只能是 Error 的子类而不是 Exception 的子类,因为许多应用程序捕获所有出现的 Exception,然后又将其放弃。

 对于可能出现异常的代码,有两种处理办法:
        第一、在方法中用try...catch语句捕获并处理异常,catach语句可以有多个,用来匹配多个异常。例如:
public void p(int x){
 try{
  ...
 }catch(Exception e){
  ...
 }finally{
  ...
 }
}
 
第二、对于处理不了的异常或者要转型的异常,在方法的声明处通过throws语句抛出异常。例如:
public void test1() throws MyException{
 ...
 if(....){
  throw new MyException();
 }
        如果每个方法都是简单的抛出异常,那么在方法调用方法的多层嵌套调用中,Java虚拟机会从出现异常的方法代码块中往回找,直到找到处理该异常的代码块为止。然后将异常交给相应的catch语句处理。如果Java虚拟机追溯到方法调用栈最底部main()方法时,如果仍然没有找到处理异常的代码块,将按照下面的步骤处理:
        第一、调用异常的对象的printStackTrace()方法,打印方法调用栈的异常信息。
        第二、如果出现异常的线程为主线程,则整个程序运行终止;如果非主线程,则终止该线程,其他线程继续运行。
        通过分析思考可以看出,越早处理异常消耗的资源和时间越小,产生影响的范围也越小。因此,不要把自己能处理的异常也抛给调用者。
        还有一点,不可忽视:finally语句在任何情况下都必须执行的代码,这样可以保证一些在任何情况下都必须执行代码的可靠性。比如,在数据库查询异常的时候,应该释放JDBC连接等等。finally语句先于return语句执行,而不论其先后位置,也不管是否try块出现异常。finally语句唯一不被执行的情况是方法执行了System.exit()方法。System.exit()的作用是终止当前正在运行的 Java 虚拟机。finally语句块中不能通过给变量赋新值来改变return的返回值,也建议不要在finally块中使用return语句,没有意义还容易导致错误。
 
        最后还应该注意一下异常处理的语法规则:
        第一、try语句不能单独存在,可以和catch、finally组成 try...catch...finally、try...catch、try...finally三种结构,catch语句可以有一个或多个,finally语句最多一个,try、catch、finally这三个关键字均不能单独使用。
        第二、try、catch、finally三个代码块中变量的作用域分别独立而不能相互访问。如果要在三个块中都可以访问,则需要将变量定义到这些块的外面。
        第三、多个catch块时候,Java虚拟机会匹配其中一个异常类或其子类,就执行这个catch块,而不会再执行别的catch块。
        第四、throw语句后不允许有紧跟其他语句,因为这些没有机会执行。
        第五、如果一个方法调用了另外一个声明抛出异常的方法,那么这个方法要么处理异常,要么声明抛出。
 
        那怎么判断一个方法可能会出现异常呢?一般来说,方法声明的时候用了throws语句,方法中有throw语句,方法调用的方法声明有throws关键字。
 
        throw和throws关键字的区别
        throw用来抛出一个异常,在方法体内。语法格式为:throw 异常对象。
        throws用来声明方法可能会抛出什么异常,在方法名后,语法格式为:throws 异常类型1,异常类型2...异常类型n。

posted @ 2012-08-12 07:44 leoChiang 阅读(1061) | 评论 (0)编辑 收藏

    JAVA平台提供了两个类:StringStringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。String类表示内容不可改变的字符串。而StringBuffer类表示内容可以被修改的字符串。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可以使用StringBuffers来动态构造字符数据。另外,String实现了equals方法,new String(“abc”).equals(new String(“abc”)的结果为true,StringBuffer没有实现equals方法,所以,new StringBuffer(“abc”).equals(new StringBuffer(“abc”)的结果为false

String覆盖了equals方法和hashCode方法,而StringBuffer没有覆盖equals方法和hashCode方法,所以,将StringBuffer对象存储进Java集合类中时会出现问题。

StringBufferStringBuilder类都表示内容可以被修改的字符串,StringBuilder是线程不安全的,运行效率高,如果一个字符串变量是在方法里面定义,这种情况只可能有一个线程访问它,不存在不安全的因素了,则用StringBuilder。如果要在类里面定义成员变量,并且这个类的实例对象会在多线程环境下使用,那么最好用StringBuffer

    另: 逗号分隔字符串转换成数组、

如果不查jdk api,我很难写出来!我可以说说我的思路:

1.        用正则表达式,代码大概为:String [] result = orgStr.split(“,”);

2.        StingTokenizer ,代码为:StringTokenizer  tokener = StringTokenizer(orgStr,”,”);

String [] result = new String[tokener .countTokens()];

Int i=0;

while(tokener.hasNext(){result[i++]=toker.nextToken();}

 

posted @ 2012-08-10 08:21 leoChiang 阅读(246) | 评论 (0)编辑 收藏

另有: http://blog.csdn.net/ilibaba/article/details/3866537 

1.首先,把内部类作为外部类的一个特殊的成员来看待,因此它有类成员的封闭等级:private ,protected,默认(friendly),public 它有类成员的修饰符:   static,final,abstract 

2.非静态内部类nested inner class,内部类隐含有一个外部类的指针this,因此,它可以访问外部类的一切资源(当然包括private) 
  外部类访问内部类的成员,先要取得内部类的对象,并且取决于内部类成员的封装等级。 
  非静态内部类不能包含任何static成员. 

3.静态内部类:static inner class,不再包含外部类的this指针,并且在外部类装载时初始化. 
  静态内部类能包含static或非static成员. 
  静态内部类只能访问外部类static成员. 
  外部类访问静态内部类的成员,循一般类法规。对于static成员,用类名.成员即可访问,对于非static成员,只能 
    用对象.成员进行访问 

4.对于方法中的内部类或块中内部类只能访问块中或方法中的final变量。 
类成员有两种static , non-static,同样内部类也有这两种 
non-static 内部类的实例,必须在外部类的方法中创建或通过外部类的实例来创建(OuterClassInstanceName.new innerClassName(ConstructorParameter)),并且可直接访问外部类的信息,外部类对象可通过OuterClassName.this来引用 
static 内部类的实例, 直接创建即可,没有对外部类实例的引用。 
内部类不管static还是non-static都有对外部类的引用 
non-static 内部类不允许有static成员  
方法中的内部类只允许访问方法中的final局部变量和方法的final参数列表,所以说方法中的内部类和内部类没什麽区别。但方法中的内部类不能在方法以外访问,方法中不可以有static内部类 
匿名内部类如果继承自接口,必须实现指定接口的方法,且无参数 
匿名内部类如果继承自类,参数必须按父类的构造函数的参数传递
  

内部类的作用

java 中的内部类和接口加在一起,可以的解决常被 C++ 程序员抱怨 java 中存在的一个问题??没有多继承。实际上,C++ 的多继承设计起来很复杂,而 java 通过内部类加上接口,可以很好的实现多继承的效果。  

内部类:一个内部类的定义是定义在另一个内部的类。 
原因是: 
1.一个内部类的对象能够访问创建它的对象的实现,包括私有数据。 
2.对于同一个包中的其他类来说,内部类能够隐藏起来。 
3.匿名内部类可以很方便的定义回调。 
4.使用内部类可以非常方便的编写事件驱动程序。 
posted @ 2012-08-10 08:02 leoChiang 阅读(199) | 评论 (0)编辑 收藏

    java内部类分为:成员内部类,局部内部类,静态内部类,匿名内部类。
1) 成员内部类:
        什么是成员内部类:作为外部类的成员存在,与外部类的属性和方法并列。注意:成员内部类中不能定义静态变量,但是可以访问外部类的所有成员。
          成员内部类的用处:   见最后的内部类作用。   
        成员内部类的优点: 1.内部类作为外部类的成员可以访问外部类的所有成员包括私有成员或属性。2.用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。
        成员内部类注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。
 
 public class Outer{
private static int i = 1;
private int j=10;
private int k=20;
public static void outer_f1(){
    //do more something
    System.out.println("outer's outer_f1");
}
public void out_f2(){
    //do more something
    
    
}

//成员内部类
class Inner{
//static int inner_i =100; //内部类中不允许定义静态变量
int j=100;//内部类中外部类的实例变量可以共存
int inner_i=1;
void inner_f1(){
    System.out.println(i);//外部类的变量如果和内部类的变量没有同名的,则可以直接用变量名访问外部类的变量
    System.out.println(j);//在内部类中访问内部类自己的变量直接用变量名
    System.out.println(this.j);//也可以在内部类中用"this.变量名"来访问内部类变量
    
//访问外部类中与内部类同名的实例变量可用"外部类名.this.变量名"。
    System.out.println(k);//外部类的变量如果和内部类的变量没有同名的,则可以直接用变量名访问外部类的变量
    
    outer_f1(); //可以直接访问外部类的静态方法
//    outer_f2(); //compile error,访问外部类非静态方法,必须使用外部类的实例,如下一句
    Outer.this.out_f2();


}
//外部类的非静态方法访问成员内部类
public void outer_f3(){
    Inner inner = new Inner();
    inner.inner_f1();
}

//外部类的静态方法访问成员内部类,与在外部类外部访问成员内部类一样
public static void outer_f4(){
    //step1 建立外部类对象
    Outer out = new Outer();
    //***step2 根据外部类对象建立内部类对象***
    Inner inner=out.new Inner();
    //step3 访问内部类的方法
    inner.inner_f1();
}

public static void main(String[] args){
    outer_f4();
}
}
2) 局部内部类:
        什么是局部内部类: 即在方法中定义的内部类,与局部变量类似,在局部内部类前不加修饰符public或private,其范围为定义它的代码块。 
        局部内部类的用处:   见最后的内部类作用。  
        局部内部类的优点:在类外不可直接生成局部内部类(保证局部内部类对外是不可见的)。要想使用局部内部类时需要生成对象,对象调用方法,在方法中才能调用其局部内部类。通过内部类和接口达到一个强制的弱耦合,用局部内部类来实现接口,并在方法中返回接口类型,使局部内部类不可见,屏蔽实现类的可见性。  
       局部内部类注意:局部内部类中不可定义静态变量,可以访问外部类的局部变量(即方法内的变量),但是变量必须是final的。  
public class Outer {
    private int s = 100;
    private int out_i = 1;

    public void f(final int k) {
        final int s = 200;
        int i = 1;
        final int j = 10;
        class Inner { // 定义在方法内部
            int s = 300;// 可以定义与外部类同名的变量

            
// static int m = 20;//不可以定义静态变量
            Inner(int k) {
                inner_f(k);
            }

            int inner_i = 100;

            void inner_f(int k) {
                System.out.println(out_i);// 如果内部类没有与外部类同名的变量,在内部类中可以直接访问外部类的实例变量
                System.out.println(k);// *****可以访问外部类的局部变量(即方法内的变量),但是变量必须是final的*****
//                 System.out.println(i);  //compile error,i必须是final的
                System.out.println(s);// 如果内部类中有与外部类同名的变量,直接用变量名访问的是内部类的变量
                System.out.println(this.s);// 用"this.变量名" 访问的也是内部类变量
                System.out.println(Outer.this.s);// 用外部"外部类类名.this.变量名"
                                                    
// 访问的是外部类变量
            }
        } //inner
        new Inner(k);
    }

    public static void main(String[] args) {
        // 访问局部内部类必须先有外部类对象
        Outer out = new Outer();
        out.f(3);
    }

}
  
3)静态内部类:
    什么是静态内部类:  静态内部类定义在类中,任何方法外,用static定义。  
    静态内部类的用处:   见最后的内部类作用。  
    静态内部类的优点:  
   静态内部类注意:静态内部类中可以定义静态或者非静态的成员 ,*******生成(new)一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成: 
    Outer.Inner in=new Outer.Inner(); 
而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类。静态内部类可用private,protected,public,abstract等来修饰*******
  
   
public class Outer {
    private static int i = 1;
    private int j = 10;

    public static void outer_f1() {

    }

    public void outer_f2() {

    }

    // 静态内部类可以用public,protected,private修饰
    
// 静态内部类中可以定义静态或者非静态的成员
    static class Inner {
        static int inner_i = 100;
        int inner_j = 200;

        static void inner_f1() {
            System.out.println("Outer.i " + i);// 静态内部类只能访问外部类的静态成员
            outer_f1();// 包括静态变量和静态方法
        }

        void inner_f2() {
//             System.out.println("Outer.i"+j);// error 静态内部类不能访问外部类的非静态成员
//             outer_f2();//error 包括非静态变量和非静态方法
        }

    }

    public void outer_f3() {
        // 外部类访问内部类的静态成员:内部类.静态成员
        System.out.println(Inner.inner_i);   //100
        Inner.inner_f1();   //Outer.i 1
        
// 外部类访问内部类的非静态成员:实例化内部类即可
        Inner inner = new Inner();
        inner.inner_f2();

    }

    public static void main(String[] args) {
        new Outer().outer_f3();
    }
}

4)匿名内部类:
    什么是匿名内部类:   匿名内部类是一种特殊的局部内部类,它是通过匿名类实现接口。 
                                    IA被定义为接口。 
                                    IA I=new IA(){};    
    匿名内部类的用处:   见最后的内部类作用。  
    匿名内部类的优点:  1,一个类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是覆盖。 
                                2,只是为了获得一个对象实例,不需要知道其实际类型。 
                                3,类名没有意义,也就是不需要使用到。 
   匿名内部类注意: 一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类,没有类名,根据多态,我们使用其父类名。因他是局部内部类,那么局部内部类的所有限制都对其生效。匿名内部类是唯一一种无构造                          法类。大部分匿名内部类是用于接口回调用的。匿名内部类在编译的时候由系统自动起名Out$1.class。如果一个对象编译时的类型是接口,那么其运行的类型为实现这个接口的类。因匿名内部类无构造方法,所以其                          使用范围非常的有限。当需要多个对象时使用局部内部类,因此局部内部类的应用相对比较多。匿名内部类中不能定义构造方法。如果一个对象编译时的类型是接口,那么其运行的类型为实现这个接口的类。 
在java的事件处理的匿名适配器中,匿名内部类被大量的使用。例如在想关闭窗口时加上这样一句代码: 
frame.addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent e){
       System.exit(0);
    }
}); 

转载自:http://hnzhoujunmei.iteye.com/blog/1067335



posted @ 2012-08-09 10:12 leoChiang 阅读(192) | 评论 (0)编辑 收藏

       面向对象的特征有:封装、继承、 抽象、多态。
      封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”,防止程序相互依赖性而带来的变动影响。在面向对象的编程语言中,对象是封装的最基本单位,面向对象的封装比传统语言的封装更为清晰、更为有力。面向对象的封装就是把描述一个对象的属性和行为的代码封装在一个“模块”中,也就是一个类中,属性用变量定义,行为用方法进行定义,方法可以直接访问同一个对象中的属性。通常情况下,只要记住让变量和访问这个变量的方法放在一起,将一个类中的成员变量全部定义成私有的,只有这个类自己的方法才可以访问到这些成员变量,这就基本上实现对象的封装,就很容易找出要分配到这个类上的方法了,就基本上算是会面向对象的编程了。把握一个原则:把对同一事物进行操作的方法和相关的方法放在同一个类中,把方法和它操作的数据放在同一个类中。
      抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。例如,看到一只蚂蚁和大象,你能够想象出它们的相同之处,那就是抽象。
       在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。  
      多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。
       java实现多态的机制:靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。

        另: javaEE中的session的理解--
             session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。在服务器上,通过Session来区分每一个上网用户用户只要一连接到服务器,则立刻分配一个Session给用户
 Session主要方法:

1  服务器上通过Session来分别不同的用户-->Session ID
任何连接到服务器上的用户,服务器都会位之分配唯一的一个不会重复的Session ID
Session ID是由服务器统一管理的,人为不能控制
方法:session.getID();
长度:32

2  判断是否是新的Session
public boolean isNew();
判断当前的Session是否是新建立的Session

3  Session的属性设置
设置属性:public void setAttribute(String name,Object value)
取得属性:public Object getAttribute(String name)
删除属性:pbulic void removeAttribute(String name)
4  登陆验证
通过Session能够对用户是否登陆做出验证
public void putValue(String name,Object)-->setAttribute
public Object getValue(String name)-->getAttribute
public removeValue(String name)-->removeAttribute
此三个方法已经过时,不建议再使用

注销用户:让用户的Session失效
如果Session失效,则在Session所保留的全部操作也会消失
public void invalidate()使Session失效(手工)
如果Session长时间不被使用,则也会自动失效
5  得到Session的创建时间
public long getCreationTime()
此方法返回long类型,通过new Date()可以取得一个完成时间
取得用户最后操作的时间:public long getLastAccessedTime();

6  总结
Session将信息保存在服务器上,而Cookie保存在客户端上
Session比Cookie更安全,Session比Cookie更占资源
开发原则:Session要尽量少用--尽量少向Session中保存信息
session使用了Cookie的机制,如果Cookie被禁用,则Session也无法使用,因为客户端的session ID以cookie形式,保存在了客户端的内存当中,这个时候我们可以通过url重写,来保证session的有效性.

重写url的方法如下

resp.encodeURL(request.getRequestURL().toString());          http://phl.iteye.com/blog/699574

   


转载:  
感觉网站最好不要依赖session 

session 在做 多服务器负载的时候 

会有点麻烦 

直接用 cookie + 第三方缓存 比较的好... 

自己在两个公司呆过后得出的结论,纯属个人体会 ... 

posted @ 2012-08-07 21:19 leoChiang 阅读(172) | 评论 (0)编辑 收藏

作用域 
当前类同一package子孙类 
其他package
public√    
√    
√    
√    
protected 
√    
√    
√    
  ×  
default√    
√    
  ×  
  × 
private√    
  ×  
  ×  
  ×  

关于overload与override的区别:
   overload是重载,意思是我们可以定义一些名称相同的方法,通过定义不同的输入参数来区分这些方法,然后再调用时,VM就会根据不同的参数样式,来选择合适的方法执行。 方法重载支持多态性,因为它是Java 实现“一个接口,多个方法”范型的一种方式。要理解这一点,考虑下面这段话:在不支持方法重载的语言中,每个方法必须有一个惟一的名字。但是,你经常希望实现数据类型不同但本质上相同的方法。 
        1)使用重载时必须使用不同的参数样式
        2)对于继承来说,如果某一方法在父类中是访问权限是private,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新方法,而不会达到重载的效果。
    override是重写(比如说对接口的重写,继承中子类重写父类的方法)。
        1)覆盖的方法的标志必须要和被覆盖的方法的标志完全匹配,才能达到覆盖的效果;

        2)覆盖的方法的返回值必须和被覆盖的方法的返回一致;

        3)覆盖的方法所抛出的异常必须和被覆盖方法的所抛出的异常一致,或者是其子类;

        4)被覆盖的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行覆盖。

关于抽象类(abstract)   
      所有的对象都是通过类来描述的,然而,所有的类不一定是通过对象来描述清楚,因此不能描述的这些类定义为抽象类 。   
      抽象类与接口紧密相关。然接口又比抽象类更抽象,这主要体现在它们的差别上:1)类可以实现无限个接口,但仅能从一个抽象(或任何其他类型)类继承,从抽象类派生的类仍可实现接口,从而得出接口是用来解决多重继承问题的。2)抽象类当中可以存在非抽象的方法,可接口不能且它里面的方法只是一个声名必须用public来修饰没有具体实现的方法。3)抽象类中的成员变量可以被不同的修饰符来修饰,可接口中的成员变量默认的都是静态常量(static final)。4)这一点也是最重要的一点本质的一点"抽象类是对象的抽象,然接口是一种行为规范"。 
        package core_java;

abstract class Ch{
    public abstract void doSome();
}

class A extends Ch{
    public void doSome(){
        System.out.println("a");
    }
}

class B extends Ch{
    public void doSome(){
        System.out.println("b");
    }
}

public class TestAbstract {

    /**
     * 
@param args
     
*/
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Ch aa = new A();
        Ch bb = new B();
        
        A aaa = new A();
        B bbb = new B();
        aa.doSome();
        bb.doSome();
        aaa.doSome();
        bbb.doSome();
        
        doSomething(aa);
        doSomething(bb);
        doSomething(aaa);
        doSomething(bbb);
    }
    
    public static void doSomething(Ch a){
        a.doSome();
    }

}
posted @ 2012-08-06 09:27 leoChiang 阅读(263) | 评论 (0)编辑 收藏

package core_java;
import java.util.Scanner;

public class ExchangeArray {

    /**
     * 
@param args
     
*/
    public static int[] split2array(String str){
        String[] m = null;
        m = str.split(",");
        int[] a = new int[m.length];
        for(int i=0;i<m.length;i++){
            a[i] =  Integer.parseInt(m[i]);
        }
        return a;
    }
    
    public static int[] exchange(int[] a){
        int[] b = new int[a.length];
        for(int j=0;j<a.length;j++){
            b[j]=a[a.length-1-j];
        }
        return b;
    }
    public static int[] bubsort(int[] a){//冒泡排序
        int[] b = a;
        for (int i = 0; i < b.length; i++) {
            for(int j=i;j<b.length;j++){
                int temp;
                if(b[i]<b[j]){
                    temp = b[i];
                    b[i] = b[j];
                    b[j] = temp;
                }
            }
            
        }
        return b;
    }
    
    public static int[] selsort(int[] a){//选择排序
        int[] b = a;
        for (int i = 0; i < b.length; i++) {
            int minIndex = i;//以最小值为基准
            for(int j=i;j<b.length;j++){
                int temp1 = b[minIndex];
                int temp2 = b[j];
                if(temp1>temp2){
                    minIndex = j;
                }
            }
            if(minIndex!=i){
                int temp;
                temp = b[minIndex];
                b[minIndex] = b[i];
                b[i] = temp;
            }
        }
        return b;
    }
    
    public static void print(int[] a){
        for(int m=0;m<a.length-1;m++){
            System.out.print(a[m]+",");
        }
        System.out.print(a[a.length-1]);
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("请输入序列(以逗号隔开回车结束):");
        Scanner sc = new Scanner(System.in);
        String ss = sc.nextLine();
        String[] o = ss.split(",");
        System.out.println("原序列:");
        for (int i = 0; i < o.length-1; i++) {
            System.out.print(o[i]+",");
        }
        System.out.println(o[o.length-1]);
        int[] r = exchange(split2array(ss));
        System.out.println("处理后的序列:");
        for(int m=0;m<r.length-1;m++){
            System.out.print(r[m]+",");
        }
        System.out.println(r[r.length-1]);
        System.out.println("选择排序后的结果:");
        print(selsort(r));
        /*System.out.println();
        System.out.println("冒泡排序后的结果:");
        print(bubsort(r));
*/
    }

}

注意其中的异常:
数组越界异常           ArrayIndexOutOfBoundsException
空指针异常             NullPointerException






posted @ 2012-08-02 17:57 leoChiang 阅读(225) | 评论 (0)编辑 收藏

      首先,hashCode就是一种查找的索引值。就好比一个数组,你用数组下标来查找你的数组元素,同样,hashCode来查找hashTable中的存储元素。当然,作为散列方式的查找和存储,要比数组这种线性数据结构复杂的多。这涉及到hash函数的构造, hash   Collision等问题,数据结构中。
而每个对象在内存当中的存储组织方式就是利用这种散列方式存储,当然也就有它的 hashCode了,如果想获取这个对象在Hash表中的位置,就可以调用 Object.hashCode() 结果返回int型。还有一点需要注意的是:hashcode   相等,则对象一定一样;hashcode   不相等,对象 也可能相等(不是相同),   如果对于不等的对象构造不同的hashCode那么将会提高 hash表的性能。(具体原因可以查看数据结构中hash表的构造方式)     
       下面的两个程序是hashcode的理解:
 student.java
package core_java;

public class Student {
    private String name;
    private int age;
    public Student(String name,int age){
        this.name = name;
        this.age = age;
    }
    public int hashCode(){
        return 7*name.hashCode()+13*age;
    }

}
在同一个包下 Testhashcode.java
package core_java;

public class Testhashcode {

    /**
     * 
@param args
     
*/
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Student stu1 = new Student("aa",17);
        Student stu2 = new Student("aa",17);
        
        System.out.println(stu1);
        System.out.println(stu2);
        
        System.out.println(stu1 == stu2);

    }

}
得出的结果:
core_java.Student@55bd
core_java.Student@55bd
false
说明:1.system.out.println(Object)输出的是Object.toString(),Student类重写了hashcode方法,如果不重写则结果不一样
        2.== 比较的不仅仅是对象在虚拟机中的内存地址
        深入了解hashcode与内存分配:

HashCodeMeaning.java

package com.leo.test.action;


import java.util.ArrayList;

/**
 * 
@author      MK
 *
 * 此方法的作用是证明 java.lang.Object的hashcode 不是代表 对象所在内存地址。
 * 我产生了10000个对象,这10000个对象在内存中是不同的地址,但是实际上这10000个对象
 * 的hashcode的是完全可能相同的
 
*/
public class HashCodeMeaning {
    public static void main(String[] args) {
        ArrayList list =  new ArrayList();
        int numberExist=0;
        
        //证明hashcode的值不是内存地址
        for (int i = 0; i < 10000; i++) {
            Object obj=new Object();
            if (list.contains(obj.toString())) {
                System.out.println(obj.toString() +"  exists in the list. "+ i);
                numberExist++;
            }
            else {
                list.add(obj.toString());
            }
        }
        
        System.out.println("repetition number:"+numberExist);
        System.out.println("list size:"+list.size());
        
        //证明内存地址是不同的。
        numberExist=0;
        list.clear();
        for (int i = 0; i < 10000; i++) {
            Object obj=new Object();
            if (list.contains(obj)) {
                System.out.println(obj +"  exists in the list. "+ i);
                numberExist++;
            }
            else {
                list.add(obj);
            }
        }
        
        System.out.println("repetition number:"+numberExist);
        System.out.println("list size:"+list.size());
    }
}
运行输出结果:

java.lang.Object@922804  exists in the list. 1778
java.lang.Object@e29820  exists in the list. 2077
repetition number:2
list size:9998
repetition number:0
list size:10000

说明:
存入hashcode到list中时不同对象的hashcode有可能相等,而不同对象的内存地址是不相等的

现在脑子里还有点混乱  需要深刻理解下。
哪位可以给我点详细的资料啊?

补充:

如果一个类没有自己定义equals方法,它默认的equals方法(从Object 类继承的)就是使用==操作符,也是在比较两个变量指向的对象是否是同一对象,这时候使用equals和使用==会得到同样的结果,如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可认为两个对象的内容是相同的。




























posted @ 2012-08-01 18:37 leoChiang 阅读(4348) | 评论 (1)编辑 收藏

首先,判断一个字符串中是否含有双字节字符:
 1 String str = "test中文汉字";
 2 String regEx = "[//u4e00-//u9fa5]";
 3 
 4 /**
 5 * 判断有没有中文
 6 
*/
 7 if (str.getBytes().length == str.length()) {
 8     System.out.println("无汉字");
 9 } else {
10     System.out.println("有汉字");
11 }
12 
13 /**
14 * 如果有则打印出来
15 
*/
16 Pattern p = Pattern.compile(regEx);
17 Matcher m = p.matcher(str);
18 while (m.find()) { 
19     System.out.print(m.group(0) + "");
20 }                                                                                                                                                                                                                                                                                                                        


其次,是关于昨天的面试题街区字符串的问题:
package core_java;

public class StringInter {
    public static boolean vd(char c){
              
        boolean isGB2312=false
        byte[] bytes=(""+c).getBytes(); 
        if(bytes.length==2){ 
                    int[] ints=new int[2]; 
                    ints[0]=bytes[0]& 0xff; 
                    ints[1]=bytes[1]& 0xff; 
                    if(ints[0]>=0x81 && ints[0]<=0xFE && ints[1]>=0x40 && ints[1]<=0xFE){ 
                        isGB2312=true
                    } 
        } 
         
        return isGB2312; 
    }
    static String Interception(String ss, int nn) {
        if( nn > (ss.length())) nn = (ss.length());
        for(int i=0; i <= ss.length(); i++){
            //System.out.print("now nn is " +nn + "\n");
            if( nn <= 0 ) return ss;
            char t = ss.charAt(i);
            if(vd(t)) {    //说明是汉字 nn减二
                if(nn == 1) return ss;
                System.out.print(t);
                nn-=2;
            }
            else {                // 非汉字,nn减一
                System.out.print(t);
                nn--;
            }
        }
        return ss;
    }
    public static void main( String args[] ) {
        String a = "aま哈abcdefg"; 
        // length() =    charAt(0..)  
        
//asd我是System.out.print(a.length());
        
//Scanner in = new Scanner(System.in);
        
//String s = in.nextLine();
        
//int n = in.nextInt();
        Interception(a, 2);
    }
}





posted @ 2012-07-31 16:10 leoChiang 阅读(611) | 评论 (0)编辑 收藏

在Java中有8种基本数据类型,其中6种是数值类型,另外两种分别是字符类型和布尔类型。而6种数值类型中有4种是整数类型,另外两种是浮点类型
    基本数据类型
        ......................数值型
                                        ................整数类型(byte 1字节 short 2字节 int 4字节 long 8字节)
                                        ................浮点类型 (float 4字节 double 8字节)

        ......................字符型   (char  2字节 存储unicode编码的字符)
        
        ......................布尔型   (boolean。。。true or false)

试题一

1 switch(expr)
expr只能为整数或枚举类型   类型转换由低级到高级。。。(byte short char int)
    试题 二
     编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。但是要保证汉字不被截半个,如"我ABC"4,应该截为"我AB",输入"我ABC汉DEF"6,应该输出"我ABC",而不是"我ABC+汉的半个"。
         1 package core_java;
 2 import java.util.Scanner;
 3 
 4 public class InterceptionStr {
 5 
 6     /**
 7      * @param args
 8      */
 9     static String ss;
10     static int n;
11     public static void Interception(String[] string){
12         int count = 0;
13         String m = "[\u4e00-\u9fa5]";
14         //汉字的正则表达式
15         System.out.println("以每"+ n +"字节划分的字符串如下所示:");
16         for (int i = 0; i < string.length; i++) {
17             if(string[i].matches(m)){
18                 count = count + 2;
19             }else{
20                 count = count + 1;
21             }
22             if(count<n){
23                 System.out.print(string[i]);
24             }else if(count==n){
25                 System.out.print(string[i]);
26                 count = 0;
27                 System.out.println();
28             }else{
29                 count = 0;
30                 System.out.println();
31             }
32         }
33         
34     }
35     public static String[] setValue(){
36         //此方法将字符串转化为字符串数组
37         String[] str = new String[ss.length()];
38         //创建字符数组
39         for (int i = 0; i < str.length; i++) {
40             str[i] = ss.substring(i, i+1);
41         }
42         return str;
43     }
44     public static void main(String[] args) {
45         // TODO Auto-generated method stub
46         System.out.println("请输入字符串:");
47         Scanner scStr = new Scanner(System.in);
48         ss = scStr.next();
49         System.out.println("请输入字节数:");  
50         Scanner scByte = new Scanner(System.in);
51         n = scByte.nextInt();
52         Interception(setValue());
53         
54     }
55 
56 }
57 

 得出的结果是截取的一段一段的,比题目给出的丰富了点

 

posted @ 2012-07-30 14:06 leoChiang 阅读(171) | 评论 (0)编辑 收藏

仅列出标题
共3页: 上一页 1 2 3 下一页