java 小记

1、

request.getContextPath()  获取项目名称,如    /BiYeSheJi

getServletContext().getRealPath("/")  获取项目根目录,如  C:\install files\programing software\eclipse\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\BiYeSheJi\

 

2、前台URL中含有中文参数时,传给Java后台获取到的会是乱码,因为ISO-8859-1是Java中网络传输使用的标准字符集,String city=request.getParameter("city");得到的还是ISO-8859-1字符集,所以要转换一下,方法不止一种,如:city = new String(city.getBytes("ISO-8859-1"), "UTF-8");

 

3、20150315

Spring框架中提供一种模式,定义类的成员变量后不用写get或set方法就可以直接使用get或set,只要在变量前声明@Getter @Setter;

此外,对于进行@Autowired声明的类变量,不需要去new它,在Spring框架中会自动维护一个类对象。如果去new它也不会保存,但会产生一些影响,如如果该类在一个web接口中会被用到,则当接口请求频繁时会造成产生大量对象的恶果

 

4、20150329

Java多线程实现方法:

 (1)写一个实现Runnable接口(及里面的run方法)的类,然后启动一个线程,此类作为线程的参数,再start

    class MyRunnable implements Runnable{
        @Override
        public void run() {
            // TODO Auto-generated method stub
        }
    }
    new Thread(new MyRunnable()).start();

 (2)写一个类,继承Thread类(实现run方法),然后new此类,再start

    class MyThread extends Thread {
        public void run() {
            System.out.println("fuck");
        }
    }
    (new MyThread()).start();

 

5、20150702  参考:http://www.cnblogs.com/qinqinmeiren/archive/2011/07/19/2151683.html

  Java 编译器默认为所有的 Java 程序导入了 JDK 的 java.lang 包中所有的类(import java.lang.*;),其中定义了一些常用类,如 System、String、Object、Math 等,因此我们可以直接使用这些类而不必显式导入。但是使用其他类必须先导入。

  不像 C/C++,Java 不支持无符号类型(unsigned)。

  float 类型有效数字最长为 8 位,有效数字长度包括了整数部分和小数部分;double 类型有效数字最长为 15 位。如2.123456789f+1f 结果为3.1234567f。

  Java也有格式化输出函数,例:System.out.printf("%d*%d=%2d ", i, j, i * j)。

  String变量被初始化后,长度和内容都不可变,每次对String的操作都会生成新的String对象,不仅效率低,而且耗费大量内存空间;对于String str = new String(“abc”),实际上创建了两个String对象,一个是”abc”对象,存储在常量空间中(常量池),一个是使用new关键字为对象str申请的空间。

            Integer i1 = new Integer(1);
            Integer i2 = new Integer(1);
            // i1,i2分别位于堆中不同的内存空间
            System.out.println(i1 == i2);// 输出false

            Integer i3 = 1;
            Integer i4 = 1;
            // i3,i4指向常量池中同一个内存空间
            System.out.println(i3 == i4);// 输出true

            // 很显然,i1,i3位于不同的内存空间
            System.out.println(i1 == i3);// 输出false

            // 值大于127时,不会从常量池中取对象
            Integer i5 = 128;
            Integer i6 = 128;
            System.out.println(i5 == i6);// 输出false

 6、String、StringBuffer、StringBuilder:前者效率最低,初始化后长度、内容不可变;后两者效率更高,StringBuilder类和StringBuffer类功能基本相似,方法也差不多,主要区别在于StringBuffer类的方法是多线程安全的,而StringBuilder不是线程安全的,相比而言,StringBuilder类会略微快一点。

线程安全:

    • StringBuffer:线程安全
    • StringBuilder:线程不安全

速度:
一般情况下,速度从快到慢为 StringBuilder > StringBuffer > String,当然这是相对的,不是绝对的。

使用环境:

    • 操作少量的数据使用 String;
    • 单线程操作大量数据使用 StringBuilder;
    • 多线程操作大量数据使用 StringBuffer。

7、Java修饰符

  Java 通过修饰符来控制类、属性和方法的访问权限和其他功能,通常放在语句的最前端,分为访问修饰符和非访问修饰符。访问修饰符也叫访问控制符,是指能够控制类、成员变量、方法的使用权限的关键字

修饰符 说明
public 共有的,对所有类可见。
protected 受保护的,对同一包内的类和所有子类可见。
private 私有的,在同一类内可见。
默认的 在同一包内可见。默认不使用任何修饰符。

8、Java变量作用域

  在Java中,变量的作用域分为四个级别:类级(全局级变量或静态变量,需要使用static关键字修饰)、对象实例级(成员变量,实例化后才会分配内存空间,才能访问)、方法级(在方法内部定义的变量,就是局部变量)、块级(定义在一个块内部的变量,变量的生存周期就是这个块)。

  • 方法内部除了能访问方法级的变量,还可以访问类级和实例级的变量。
  • 块内部能够访问类级、实例级变量,如果块被包含在方法内部,它还可以访问方法级的变量。
  • 方法级和块级的变量必须被显示地初始化,否则不能访问。

9、this关键字

   this 关键字用来表示当前对象本身,或当前类的一个实例,通过 this 可以调用本对象的所有方法和属性。

    • 构造方法中区分形参和类的成员变量:
          public String name;
          public int age;   
          public Demo(String name, int age){
                this.name = name;
                this.age = age;
            }
          
    • 构造方法重载时作为方法名初始化对象:
      public class Demo{
           public Demo(){
               this("博客园", 10);
           }
           public Demo(String name, int age){
               this.name = name;
               this.age = age;
           }
      }
    • 作为对象参数传递
      public class Demo{
          public static void main(String[] args){
              B b = new B(new A());
          }
      }
      class A{
          public A(){
              new B(this).print();  // 匿名对象
          }
          public void print(){
              System.out.println("Hello from A!");
          }
      }
      class B{
          A a;
          public B(A a){
              this.a = a;
          }
          public void print() {
              a.print();
              System.out.println("Hello from B!");
          }
      }
      View Code

10、构造方法不能被继承,要使用父类的构造方法,可以通过super关键字

11、重写(覆盖)和重载:

  前者子类继承父类,覆盖父类的方法,参数类型、个数、顺序、返回类型必须与父类一致,可通过super调用父类被覆盖的方法(父类被覆盖的方法还能用);

  后者在一个类中有多个同名方法,只要参数类型、个数、顺序至少一者不同即可;

  父类的一个方法只能被子类覆盖一次(否则一个类中有参数列表和返回类型都完全相同的方法会报错),而一个方法可以在所有的类中可以被重载多次。

  重写的方法不能比原方法抛出更多的异常;被重写的方法不能是final类型、不能为private、不能为static

12、面向对象的三大特性:封装、继承、多态。

  多态存在的三个必要条件:要有继承、要有重写、父类变量引用子类对象。

  多态可以理解为父类既可以指向父类实例,也可以指向其子类的实例,对于一个方法,既可以表现父类的行为,如果被子类继承则表现为子类的行为,从而有不同的表现形式。

  当使用多态方式调用方法时:

  • 首先检查父类中是否有该方法,如果没有,则编译错误;如果有,则检查子类是否覆盖了该方法。(可见,具有不同表现形式即多态是相对于被继承的方法来说的)
  • 如果子类覆盖了该方法,就调用子类的方法,否则调用父类方法。

13、多态性相关问题:

  (1)如何判断一个变量所实际引用的对象的类型 ? C++使用runtime-type information(RTTI),Java 使用 instanceof 操作符:如果变量引用的是当前类或它的子类的实例,instanceof 返回 true,否则返回 false。如下:

public final class Demo{
    public static void main(String[] args) {
        // 引用 People 类的实例
        People obj = new People();
        if(obj instanceof Object){
            System.out.println("我是一个对象");
        }
        if(obj instanceof People){
            System.out.println("我是人类");
        }
        if(obj instanceof Teacher){
            System.out.println("我是一名教师");
        }
        if(obj instanceof President){
            System.out.println("我是校长");
        }
        System.out.println("-----------");  // 分界线
       
        // 引用 Teacher 类的实例
        obj = new Teacher();
        if(obj instanceof Object){
            System.out.println("我是一个对象");
        }
        if(obj instanceof People){
            System.out.println("我是人类");
        }
        if(obj instanceof Teacher){
            System.out.println("我是一名教师");
        }
        if(obj instanceof President){
            System.out.println("我是校长");
        }
    }
}
class People{ }
class Teacher extends People{ }
class President extends Teacher{ }
View Code

  (2)对象类型转换

  这里所说的对象类型转换,是指存在继承关系的对象,不是任意类型的对象。当对不存在继承关系的对象进行强制类型转换时,java 运行时将抛出 java.lang.ClassCastException 异常。子类向父类转换称为“向上转型”(如父类变量引用子类对象),将父类向子类转换称为“向下转型”(有些时候为了完成某些父类没有的功能,我们需要将向上转型后的子类对象再转成子类,调用子类的方法,这就是向下转型),向上转型会自动进行,向下转型的对象必须是当前引用类型的子类。

  不能直接将父类的对象强制转换为子类类型,只能将向上转型后的子类对象再次转换为子类类型。也就是说,子类对象必须向上转型后,才能再向下转型。因为向下转型存在风险,所以在接收到父类的一个引用时,请务必使用 instanceof 运算符来判断该对象是否是你所要的子类。示例如下:

public class Demo {
    public static void main(String args[]) {
        SuperClass superObj = new SuperClass();
        SonClass sonObj = new SonClass();
        // superObj 不是 SonClass 类的实例
        if(superObj instanceof SonClass){
            SonClass sonObj1 = (SonClass)superObj;
        }else{
            System.out.println("①不能转换");
        }
        superObj = sonObj;
        // superObj 是 SonClass 类的实例
        if(superObj instanceof SonClass){
            SonClass sonObj2 = (SonClass)superObj;
        }else{
            System.out.println("②不能转换");
        }
    }
}
class SuperClass{ }
class SonClass extends SuperClass{ }
View Code

 14、final

  在 Java 中,声明类、变量和方法时,可使用关键字 final 来修饰。final 所修饰的数据具有“终态”的特征,表示“最终的”意思。具体规定如下:

  • final 修饰的类不能被继承。
  • final 修饰的方法不能被子类重写。
  • final 修饰的变量(成员变量或局部变量)即成为常量,只能赋值一次。
    • final 修饰的成员变量必须在声明的同时赋值,如果在声明的时候没有赋值,那么只有 一次赋值的机会,而且只能在构造方法中显式赋值,然后才能使用。
    • final 修饰的局部变量可以只声明不赋值,然后再进行一次性的赋值。
    • 如果将引用类型(任何类的类型)的变量标记为 final,那么该变量不能指向任何其它对象。但可以改变对象的内容,因为只有引用本身是 final 的。

15、内部类

  在 Java 中,允许在一个类(或方法、语句块)的内部定义另一个类,称为内部类(Inner Class),有时也称为嵌套类(Nested Class)。内部类和外层封装它的类之间存在逻辑上的所属关系,一般只用在定义它的类或语句块之内,实现一些没有通用意义的功能逻辑,在外部引用它时必须给出完整的名称。参见 这 里

  内部类是 Java 1.1 的新增特性,看似增加了—些优美有趣,实属没必要的特性;内部类语法很复杂,严重破坏了良好的代码结构, 违背了Java要比C++更加简单的设计理念。

 

16、抽象类和接口

  抽象类:

  抽象类是指包含零或多个抽象方法的类,类名和抽象方法均由abstract修饰,如 abstract class A{int a,b; abstract void getA(); int getB(){return b;}};

  抽象类可以有实现了的方法、可以有初始化或未初始化的成员变量,当没有抽象方法时,它和普通类类似,只是多了abstract修饰;

  抽象类不能用来创建实例(故不能有构造方法),只能用继承它的子类创建实例,但可以用抽象类定义引用变量并指向子类对象。

  接口:

  接口是特殊的抽象类,是若干常量和抽象方法的集合,接口名由interface修饰;

  接口不能用来创建实例(故不能有构造方法),只能用实现了该接口的类来创建实例,但可以用接口定义变量指向其实现类的对象;

  接口中声明的成员变量默认都是 public static final 的,由于是final,必须显示地初始化且实现类不能修改其值。在常量声明时可以省略这些修饰符;

  接口中只能定义抽象方法,这些方法默认为 public abstract 的,因而在声明方法时可以省略这些修饰符。试图在接口中定义实例变量、非抽象的实例方法及静态方法,都是非法的。

// 接口成员变量必须是public static void,可省略修饰符
// 接口方法必须是public abstract,可省略修饰符
// 上述两者修饰符可省略,在显示指定修饰符时,与上述一个修饰符相悖的都是非法的
interface SataHdd {
    // 连接线的数量
    public int connectLine; // 编译出错,connectLine被看做静态常量,必须显式初始化

    // 写数据
    protected void writeData(String data); // 编译出错,必须是public类型
    // 读数据

    public static String readData(){ //编译出错,接口中不能包含静态方法
        return "数据"; //编译出错,接口中只能包含抽象方法,
    }
}

class BBB implements SataHdd {
    public BBB() {
        this.connectLine = 33;// 错误,connectLine为public static final,值不能更改
    }

    public int getData() {
        return 0;
    }
}
View Code

 

你可能感兴趣的:(java)