美文网首页
Java基础-难点汇总

Java基础-难点汇总

作者: 田永威 | 来源:发表于2017-03-02 13:41 被阅读825次

    参考链接:菜鸟教程 的Java部分,可以很快的看一遍,以免遗漏,只记录下我认为比较生疏的部分。

    1.命令行执行Java程序

    以下我们通过一个简单的实例来展示 Java 编程,创建文件 HelloWorld.java(文件名需与类名一致), 代码如下:

    实例
    public class HelloWorld {
        public static void main(String []args) {
            System.out.println("Hello World");
        }
    }
    
    $ javac HelloWorld.java (会生成HelloWorld.class 字节码文件)
    $ java HelloWorld
    Hello World
    

    Java修饰符

    像其他语言一样,Java可以使用修饰符来修饰类中方法和属性。主要有两类修饰符:
    访问控制修饰符 : default, public , protected, private
    非访问控制修饰符 : final, abstract, strictfp
    在后面的章节中我们会深入讨论Java修饰符。

    Java枚举

    Java 5.0引入了枚举,枚举限制变量只能是预先设定好的值。使用枚举可以减少代码中的bug。
    例如,我们为果汁店设计一个程序,它将限制果汁为小杯、中杯、大杯。这就意味着它不允许顾客点除了这三种尺寸外的果汁。

    实例
    class FreshJuice {
       enum FreshJuiceSize{ SMALL, MEDIUM , LARGE }
       FreshJuiceSize size;
    }
     
    public class FreshJuiceTest {
       public static void main(String []args){
          FreshJuice juice = new FreshJuice();
          juice.size = FreshJuice. FreshJuiceSize.MEDIUM  ;
       }
    }
    

    构造方法

    每个类都有构造方法。如果没有显式地为类定义构造方法,Java编译器将会为该类提供一个默认构造方法。
    在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。

    源文件声明规则

    • 一个源文件中只能有一个public类
    • 一个源文件可以有多个非public类
    • 源文件的名称应该和public类的类名保持一致。例如:源文件中public类的类名是Employee,那么源文件应该命名为Employee.java。
    • 如果一个类定义在某个包中,那么package语句应该在源文件的首行。
    • 如果源文件包含import语句,那么应该放在package语句和类定义之间。如果没有package语句,那么import语句应该在源文件中最前面。
    • import语句和package语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。

    内置数据类型

    Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。

    • byte 8位
    • short 16位
    • int 32位
    • long 64位
    • float 单精度 32位 浮点数不能用来表示精确的值,如货币
    • double 双精度 64位 同样不能表示精确的值,如货币;浮点数的默认类型为double类型
    • boolean
    • char char类型是一个单一的16位Unicode字符

    八种基本类型都有相应的包装类——首字母大写, 除了 char --> Character

    Java常量

    常量在程序运行时,不会被修改的量。
    在 Java 中使用 final 关键字来修饰常量,声明方式和变量类似:

    final double PI = 3.1415927;
    

    Java局部变量

    局部变量声明在方法、构造方法或者语句块中;
    局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁;
    访问修饰符不能用于局部变量;
    局部变量只在声明它的方法、构造方法或者语句块中可见;
    局部变量是在栈上分配的。
    局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。

    实例变量

    实例变量声明在一个类中,但在方法、构造方法和语句块之外;
    当一个对象被实例化之后,每个实例变量的值就跟着确定;
    实例变量在对象创建的时候创建,在对象被销毁的时候销毁;
    实例变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量信息;
    实例变量可以声明在使用前或者使用后;
    访问修饰符可以修饰实例变量;
    实例变量对于类中的方法、构造方法或者语句块是可见的。一般情况下应该把实例变量设为私有。通过使用访问修饰符可以使实例变量对子类可见;
    实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。变量的值可以在声明时指定,也可以在构造方法中指定;
    实例变量可以直接通过变量名访问。但在静态方法以及其他类中,就应该使用完全限定名:ObejectReference.VariableName。

    类变量(静态变量)

    类变量也称为静态变量,在类中以static关键字声明,但必须在方法构造方法和语句块之外。
    无论一个类创建了多少个对象,类只拥有类变量的一份拷贝。
    静态变量除了被声明为常量外很少使用。常量是指声明为public/private,final和static类型的变量。常量初始化后不可改变。
    静态变量储存在静态存储区。经常被声明为常量,很少单独使用static声明变量。
    静态变量在程序开始时创建,在程序结束时销毁。
    与实例变量具有相似的可见性。但为了对类的使用者可见,大多数静态变量声明为public类型。
    默认值和实例变量相似。数值型变量默认值是0,布尔型默认值是false,引用类型默认值是null。变量的值可以在声明的时候指定,也可以在构造方法中指定。此外,静态变量还可以在静态语句块中初始化。
    静态变量可以通过:ClassName.VariableName的方式访问。
    类变量被声明为public static final类型时,类变量名称一般建议使用大写字母。如果静态变量不是public和final类型,其命名方式与实例变量以及局部变量的命名方式一致。

    访问控制修饰符

    Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java支持4种不同的访问权限。
    默认的,也称为 default,在同一包内可见,不使用任何修饰符。
    私有的,以 private 修饰符指定,在同一类内可见。
    共有的,以 public 修饰符指定,对所有类可见。
    受保护的,以 protected 修饰符指定,对同一包内的类和所有子类可见。

    非访问修饰符

    为了实现一些其他的功能,Java 也提供了许多非访问修饰符。
    static 修饰符,用来创建类方法和类变量。
    final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
    abstract 修饰符,用来创建抽象类和抽象方法。
    synchronized 和 volatile修饰符,主要用于线程的编程。
    transient 用于非持久化修饰

    abstract 修饰符

    抽象类:
    抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。
    一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。
    抽象类可以包含抽象方法和非抽象方法。

    实例
    abstract class Caravan{
       private double price;
       private String model;
       private String year;
       public abstract void goFast(); //抽象方法
       public abstract void changeColor();
    }
    

    抽象方法
    抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。
    抽象方法不能被声明成 final 和 static。
    任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。
    如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。
    抽象方法的声明以分号结尾,例如:public abstract sample();。

    实例
    public abstract class SuperClass{
        abstract void m(); //抽象方法
    }
     
    class SubClass extends SuperClass{
         //实现抽象方法
          void m(){
              .........
          }
    }
    

    synchronized 修饰符

    synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。

    实例
    public synchronized void showDetails(){
    .......
    }
    

    transient 修饰符

    序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。
    该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。

    实例
    public transient int limit = 55;   // 不会持久化
    public int b; // 持久化
    

    volatile 修饰符

    volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
    一个 volatile 对象引用可能是 null。

    实例
    public class MyRunnable implements Runnable
    {
        private volatile boolean active;
        public void run()
        {
            active = true;
            while (active) // 第一行
            {
                // 代码
            }
        }
        public void stop()
        {
            active = false; // 第二行
        }
    }
    

    通常情况下,在一个线程调用 run() 方法(在 Runnable 开启的线程),在另一个线程调用 stop() 方法。 如果 第一行 中缓冲区的 active 值被使用,那么在 第二行 的 active 值为 false 时循环不会停止。
    但是以上代码中我们使用了 volatile 修饰 active,所以该循环会停止。

    instanceof 运算符

    该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)。
    instanceof运算符使用格式如下:

    String name = "James";
    boolean result = name instanceof String; // 由于 name 是 String 类型,所以返回真
    

    如果被比较的对象兼容于右侧类型,该运算符仍然返回true。
    看下面的例子:

    class Vehicle {}
     
    public class Car extends Vehicle {
       public static void main(String args[]){
          Vehicle a = new Car();
          boolean result =  a instanceof Car;
          System.out.println( result);
       }
    }
    

    Java Number 类

    所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。
    一般我们要创建一个类的对象实例的时候,我们会这样:

     Class a = new Class(parameter);
    

    当我们创建一个Integer对象时,却可以这样:

     Integer i = 100; //(注意:不是 int i = 100; )
    

    实际上,执行上面那句代码的时候,系统为我们执行了:

    Integer i = Integer.valueOf(100); 
    

    此即基本数据类型的自动装箱功能。
    自动装箱/拆箱 http://www.cnblogs.com/danne823/archive/2011/04/22/2025332.html

    Java StringBuffer 和 StringBuilder 类

    当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
    和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象
    StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
    由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

    Java 数组

    double[] myList;  // 首选的方法
    double myList2[]; //  效果相同,但不是首选
    方法
    
    dataType[] arrayRefVar = new dataType[arraySize];
    
    dataType[] arrayRefVar = {value0, value1, ..., valuek};
    

    Arrays 类

    java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。
    具有以下功能:
    给数组赋值:通过 fill 方法。
    对数组排序:通过 sort 方法,按升序。
    比较数组:通过 equals 方法比较数组中元素值是否相等。
    查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。

    Java 日期时间

    java.util 包提供了 Date 类来封装当前的日期和时间。
    使用 SimpleDateFormat 格式化日期
    简单的 DateFormat 格式化编码

    Calendar类
    Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可。

    GregorianCalendar类
    Calendar类实现了公历日历,GregorianCalendar是Calendar类的一个具体实现。

    命令行参数的使用

    public class CommandLine {
       public static void main(String args[]){ 
          for(int i=0; i<args.length; i++){
             System.out.println("args[" + i + "]: " +
                                               args[i]);
          }
       }
    }
    

    如下所示,运行这个程序:

    $ javac CommandLine.java 
    $ java CommandLine this is a command line 200 -100
    args[0]: this
    args[1]: is
    args[2]: a
    args[3]: command
    args[4]: line
    args[5]: 200
    args[6]: -100
    

    构造方法没有返回值

    可变参数是指长度可变,并且必须是参数列表中的最后一个形参

    typeName... parameterName

    读写文件

    如前所述,一个流被定义为一个数据序列。输入流用于从源读取数据,输出流用于向目标写数据。
    下图是一个描述输入流和输出流的类层次图。

    IO.jpg

    异常

    12-130Q1234I6223.jpg

    throws/throw 关键字:

    import java.io.*;
    public class className
    {
      public void deposit(double amount) throws RemoteException
      {
        // Method implementation
        throw new RemoteException();
      }
      //Remainder of class definition
    }
    

    声明自定义异常

    在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。
    所有异常都必须是 Throwable 的子类。
    如果希望写一个检查性异常类,则需要继承 Exception 类。
    如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。
    可以像下面这样定义自己的异常类:
    class MyException extends Exception{
    }
    只继承Exception 类来创建的异常类是检查性异常类。
    下面的 InsufficientFundsException 类是用户定义的异常类,它继承自 Exception。
    一个异常类和其它任何类一样,包含有变量和方法。

    // 文件名InsufficientFundsException.java
    import java.io.*;
     
    public class InsufficientFundsException extends Exception
    {
      private double amount;
      public InsufficientFundsException(double amount)
      {
        this.amount = amount;
      } 
      public double getAmount()
      {
        return amount;
      }
    }
    

    为了展示如何使用我们自定义的异常类,
    在下面的 CheckingAccount 类中包含一个 withdraw() 方法抛出一个 InsufficientFundsException 异常。
    CheckingAccount.java 文件代码:

    // 文件名称 CheckingAccount.java
    import java.io.*;
     
    public class CheckingAccount
    {
       private double balance;
       private int number;
       public CheckingAccount(int number)
       {
          this.number = number;
       }
       public void deposit(double amount)
       {
          balance += amount;
       }
       public void withdraw(double amount) throws
                                  InsufficientFundsException
       {
          if(amount <= balance)
          {
             balance -= amount;
          }
          else
          {
             double needs = amount - balance;
             throw new InsufficientFundsException(needs);
          }
       }
       public double getBalance()
       {
          return balance;
       }
       public int getNumber()
       {
          return number;
       }
    }
    

    下面的 BankDemo 程序示范了如何调用 CheckingAccount 类的 deposit() 和 withdraw() 方法。
    BankDemo.java 文件代码:

    //文件名称 BankDemo.java
    public class BankDemo
    {
       public static void main(String [] args)
       {
          CheckingAccount c = new CheckingAccount(101);
          System.out.println("Depositing $500...");
          c.deposit(500.00);
          try
          {
             System.out.println("\nWithdrawing $100...");
             c.withdraw(100.00);
             System.out.println("\nWithdrawing $600...");
             c.withdraw(600.00);
          }catch(InsufficientFundsException e)
          {
             System.out.println("Sorry, but you are short $"
                                      + e.getAmount());
             e.printStackTrace();
          }
        }
    }
    

    编译上面三个文件,并运行程序 BankDemo,得到结果如下所示:

    Depositing $500...
    
    Withdrawing $100...
    
    Withdrawing $600...
    Sorry, but you are short $200.0
    InsufficientFundsException
            at CheckingAccount.withdraw(CheckingAccount.java:25)
            at BankDemo.main(BankDemo.java:13)
    

    相关文章

      网友评论

          本文标题:Java基础-难点汇总

          本文链接:https://www.haomeiwen.com/subject/vkqhgttx.html