java学习笔记

作者: xld | 来源:发表于2018-02-06 15:02 被阅读48次

    书摘(菜鸟教程)


    java小感


    类型\范围 同类 同包 不同包子类 不同包非子类
    private yes
    default yes yes
    protected yes yes yes
    public yes yes yes yes

    定义
    class Point<T1, T2>
    
    引用
    Point<Integer, Integer> p1 = new Point<Integer, Integer>();
    
    Point <Double, String> p2 = new Point<Double, String>();
            p2.setX(25.3);
            p2.setY("东京109度");
    
    

    普通类的定义相比,上面的代码在类名后面多出了 <T1, T2>,T1, T2 是自定义的标识符,也是参数,用来传递数据的类型,而不是数据的值,我们称之为类型参数。在泛型中,不但数据的值可以通过参数传递,数据的类型也可以通过参数传递。T1, T2 只是数据类型的占位符,运行时会被替换为真正的数据类型。


    • 静态变量和静态方法能够通过类名来访问,不需要创建一个类的对象来访问该类的静态成员
    public class Demo {
        static int i = 10;
        int j;
        Demo() {
            this.j = 20;
        }
        public static void main(String[] args) {
            System.out.println("类变量 i=" + Demo.i);
            Demo obj = new Demo();
            System.out.println("实例变量 j=" + obj.j);
        }
    }
    运行结果:
    类变量 i=10
    实例变量 j=20
    

    • 在 Java 中,声明类、变量和方法时,可使用关键字 final 来修饰。final 所修饰的数据具有“终态”的特征,表示“最终的”意思。具体规定如下:
      final 修饰的类不能被继承。
      final 修饰的方法不能被子类重写。
      final 修饰的变量(成员变量或局部变量)即成为常量,只能赋值一次。
      final 修饰的成员变量必须在声明的同时赋值,如果在声明的时候没有赋值,那么只有 一次赋值的机会,而且只能在构造方法中显式赋值,然后才能使用。
      final 修饰的局部变量可以只声明不赋值,然后再进行一次性的赋值。

    java尝试

    J2SE与J2EE、J2ME之间的关系可以通过下图来表示:

    三者的包含关系
    HelloWorld.java(文件名需与类名一致)
    public class HelloWorld {
        public static void main(String[] args) {
            System.out.println("Hello World");
        }
    }
    
    操作与输出
    $ javac HelloWorld.java
    $ java HelloWorld
    Hello World
    
    解析

    执行命令解析:
    以上我们使用了两个命令 javac 和 java。

    javac 后面跟着的是java文件的文件名,例如 HelloWorld.java。 该命令用于将 java 源文件编译为 class 字节码文件,如: javac HelloWorld.java。

    运行javac命令后,如果成功编译没有错误的话,会出现一个 HelloWorld.class 的文件。

    java 后面跟着的是java文件中的类名,例如 HelloWorld 就是类名,如: java HelloWorld。

    注意:java命令后面不要加.class。


    基础语法

    Java 基础语法

    一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。

    • 对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
    • 类:类是一个模板,它描述一类对象的行为和状态。
    • 方法:方法就是行为,一个类可以有很多方法。逻辑运算、数据修改以及所有动作都是在方法中完成的。
    • 实例变量:每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定。
    注意
    • 大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的。
    • 类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass 。
    • 方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
    • 源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记Java是大小写敏感的),文件名的后缀为.java。(如果文件名和类名不相同则会导致编译错误)。
    • 主方法入口:所有的Java 程序由public static void main(String []args)方法开始执行。
    Java标识符

    Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。

    关于Java标识符,有以下几点需要注意:

    所有的标识符都应该以字母(A-Z或者a-z),美元符()、或者下划线(_)开始 首字符之后可以是字母(A-Z或者a-z),美元符()、下划线(_)或数字的任何字符组合
    关键字不能用作标识符
    标识符是大小写敏感的
    合法标识符举例:age、$salary、_value、__1_value
    非法标识符举例:123abc、-salary

    Java修饰符

    像其他语言一样,Java可以使用修饰符来修饰类中方法和属性。主要有两类修饰符:

    访问控制修饰符 : default, public , protected, private
    非访问控制修饰符 : final, abstract, strictfp
    在后面的章节中我们会深入讨论Java修饰符。

    static是静态修饰符,什么叫静态修饰符呢?大家都知道,在程序中任何变量或者代码都是在编译时由系统自动分配内存来存储的,而所谓静态就是指在编译后所分配的内存会一直存在,直到程序退出内存才会释放这个空间,也就是只要程序在运行,那么这块内存就会一直存在。这样做有什么意义呢?在Java程序里面,所有的东西都是对象,而对象的抽象就是类,对于一个类而言,如果要使用他的成员,那么普通情况下必须先实例化对象后,通过对象的引用才能够访问这些成员,但是用static修饰的成员可以通过类名加“.”进行直接访问

    static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。

    被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。

    用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象市,不生成static变量的副本,而是类的所有实例共享同一个static变量。

    Java变量

    Java中主要有如下几种类型的变量
    局部变量
    类变量(静态变量)
    成员变量(非静态变量)

    Java数组

    数组是储存在堆上的对象,可以保存多个同类型变量。在后面的章节中,我们将会学到如何声明、构造以及初始化一个数组。

    Java枚举

    Java 5.0引入了枚举,枚举限制变量只能是预先设定好的值。使用枚举可以减少代码中的bug。

    例如,我们为果汁店设计一个程序,它将限制果汁为小杯、中杯、大杯。这就意味着它不允许顾客点除了这三种尺寸外的果汁。

    Java注释

    类似于C/C++,Java也支持单行以及多行注释。注释中的字符将被Java编译器忽略。

    public class HelloWorld {
       /* 这是第一个Java程序
        *它将打印Hello World
        * 这是一个多行注释的示例
        */
        public static void main(String []args){
           // 这是单行注释的示例
           /* 这个也是单行注释的示例 */
           System.out.println("Hello World"); 
        }
    }
    

    java 类和对象

    Java中的类

    类可以看成是创建Java对象的模板。

    通过下面一个简单的类来理解下Java中类的定义:

    public class Dog{
      String breed;
      int age;
      String color;
      void barking(){
      }
     
      void hungry(){
      }
     
      void sleeping(){
      }
    }
    

    一个类可以包含以下类型变量:

    • 局部变量:在方法、构造方法或者语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。
    • 成员变量:成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块访问。
    • 类变量:类变量也声明在类中,方法体之外,但必须声明为static类型。
    • 一个类可以拥有多个方法,在上面的例子中:barking()、hungry()和sleeping()都是Dog类的方法。
    构造方法

    每个类都有构造方法。如果没有显式地为类定义构造方法,Java编译器将会为该类提供一个默认构造方法。

    在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。

    下面是一个构造方法示例:

    public class Puppy{
        public Puppy(){
        }
     
        public Puppy(String name){
            // 这个构造器仅有一个参数:name
        }
    }
    
    创建对象

    对象是根据类创建的。在Java中,使用关键字new来创建一个新的对象。创建对象需要以下三步:

    • 声明:声明一个对象,包括对象名称和对象类型。
    • 实例化:使用关键字new来创建一个对象。
    • 初始化:使用new创建对象时,会调用构造方法初始化对象。
      下面是一个创建对象的例子:
    public class Puppy{
       public Puppy(String name){
          //这个构造器仅有一个参数:name
          System.out.println("小狗的名字是 : " + name ); 
       }
       public static void main(String []args){
          // 下面的语句将创建一个Puppy对象
          Puppy myPuppy = new Puppy( "tommy" );
       }
    }
    

    编译并运行上面的程序,会打印出下面的结果:

    小狗的名字是 : tommy

    访问实例变量和方法

    通过已创建的对象来访问成员变量和成员方法,如下所示:

    /* 实例化对象 */
    ObjectReference = new Constructor();
    /* 访问类中的变量 */
    ObjectReference.variableName;
    /* 访问类中的方法 */
    ObjectReference.MethodName();
    
    源文件声明规则

    在本节的最后部分,我们将学习源文件的声明规则。当在一个源文件中定义多个类,并且还有import语句和package语句时,要特别注意这些规则。

    • 一个源文件中只能有一个public类(java 程序是从一个 public 类的 main 函数开始执行的,(其实是main线程),就像 C 程序 是从 main() 函数开始执行一样。 只能有一个)

    • 一个源文件可以有多个非public类

    • 源文件的名称应该和public类的类名保持一致。例如:源文件中public类的类名是Employee,那么源文件应该命名为Employee.java。

    • 如果一个类定义在某个包中,那么package语句应该在源文件的首行。

    • 如果源文件包含import语句,那么应该放在package语句和类定义之间。如果没有package语句,那么import语句应该在源文件中最前面。

    • import语句和package语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。

    • 类有若干种访问级别,并且类也分不同的类型:抽象类和final类等。这些将在访问控制章节介绍。

    • 除了上面提到的几种类型,Java还有一些特殊的类,如:内部类、匿名类。

    Java包

    包主要用来对类和接口进行分类。当开发Java程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。

    Import语句

    在Java中,如果给出一个完整的限定名,包括包名、类名,那么Java编译器就可以很容易地定位到源代码或者类。Import语句就是用来提供一个合理的路径,使得编译器可以找到某个类。

    例如,下面的命令行将会命令编译器载入java_installation/java/io路径下的所有类

    import java.io.*;
    

    java基本数据类型

    引用类型
    • 在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。
    • 对象、数组都是引用数据类型。
    • 所有引用类型的默认值都是null。
    • 一个引用变量可以用来引用任何与之兼容的类型。
      例子:Site site = new Site("Runoob")。
    Java 常量

    常量在程序运行时是不能被修改的。

    在 Java 中使用 final 关键字来修饰常量,声明方式和变量类似:

    final double PI = 3.1415927;

    强制类型转换
    1. 条件是转换的数据类型必须是兼容的。

    2. 格式:(type)value type是要强制类型转换后的数据类型 实例:

    实例

    public class QiangZhiZhuanHuan{
        public static void main(String[] args){
            int i1 = 123;
            byte b = (byte)i1;//强制类型转换为byte
            System.out.println("int强制类型转换为byte后的值等于"+b);
        }
    }
    

    运行结果:

    int强制类型转换为byte后的值等于123

    Java 变量类型

    在Java语言中,所有的变量在使用前必须声明。声明变量的基本格式如下:

    type identifier [ = value][, identifier [= value] ...] ;

    格式说明:type为Java数据类型。identifier是变量名。可以使用逗号隔开来声明多个同类型变量。

    以下列出了一些变量的声明实例。注意有些包含了初始化过程。

    int a, b, c;         // 声明三个int型整数:a、 b、c
    int d = 3, e = 4, f = 5; // 声明三个整数并赋予初值
    byte z = 22;         // 声明并初始化 z
    String s = "runoob";  // 声明并初始化字符串 s
    double pi = 3.14159; // 声明了双精度浮点型变量 pi
    char x = 'x';        // 声明变量 x 的值是字符 'x'。
    

    Java语言支持的变量类型有:

    类变量:独立于方法之外的变量,用 static 修饰。
    实例变量:独立于方法之外的变量,不过没有 static 修饰。
    局部变量:类的方法中的变量。

    实例:

    public class Variable{
        static int allClicks=0;    // 类变量
     
        String str="hello world";  // 实例变量
     
        public void method(){
     
            int i =0;  // 局部变量
     
        }
    }
    

    java继承

    类的继承格式

    在 Java 中通过 extends 关键字可以申明一个类是从另外一个类继承而来的,一般形式如下:
    类的继承格式

    class 父类 {
    }
     
    class 子类 extends 父类 {
    }
    
    继承关键字

    继承可以使用 extends 和 implements 这两个关键字来实现继承,而且所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承object(这个类在 java.lang 包中,所以不需要 import)祖先类。

    • extends关键字
      在 Java 中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类。
    public class Animal { 
        private String name;   
        private int id; 
        public Animal(String myName, String myid) { 
            //初始化属性值
        } 
        public void eat() {  //吃东西方法的具体实现  } 
        public void sleep() { //睡觉方法的具体实现  } 
    } 
     
    public class Penguin  extends  Animal{ 
    }
    
    implements关键字

    使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

    public interface A {
        public void eat();
        public void sleep();
    }
     
    public interface B {
        public void show();
    }
     
    public class C implements A,B {
    }
    
    super 与 this 关键字

    super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

    this关键字:指向自己的引用。

    实例

    class Animal {
      void eat() {
        System.out.println("animal : eat");
      }
    }
     
    class Dog extends Animal {
      void eat() {
        System.out.println("dog : eat");
      }
      void eatTest() {
        this.eat();   // this 调用自己的方法
        super.eat();  // super 调用父类方法
      }
    }
     
    public class Test {
      public static void main(String[] args) {
        Animal a = new Animal();
        a.eat();
        Dog d = new Dog();
        d.eatTest();
      }
    }
    

    输出结果为:

    animal : eat
    dog : eat
    animal : eat
    
    final关键字

    final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写:

    声明类:

    final class 类名 {//类体}
    声明方法:

    修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}

    java修饰符

    Java语言提供了很多修饰符,主要分为以下两类:

    访问修饰符
    非访问修饰符
    修饰符用来定义类、方法或者变量,通常放在语句的最前端。我们通过下面的例子来说明:

    public class className {
       // ...
    }
    private boolean myFlag;
    static final double weeks = 9.5;
    protected static final int BOXWIDTH = 42;
    public static void main(String[] arguments) {
       // 方法体
    }
    
    访问控制修饰符

    Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。

    • default (即缺省,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

    • private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

    • public : 对所有类可见。使用对象:类、接口、变量、方法

    • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。

    访问控制

    修饰符 当前类 同一包内 子孙类 其他包
    public Y Y Y Y
    protected Y Y Y N
    default Y Y N N
    private Y N N N

    Java 运算符

    自增自减运算符

    1、前缀自增自减法(++a,--a): 先进行自增或者自减运算,再进行表达式运算。

    2、后缀自增自减法(a++,a--): 先进行表达式运算,再进行自增或者自减运算 实例:

    赋值运算符
    操作符 描述 例子
    << = 左移位赋值运算符 C << = 2等价于C = C << 2
    >> = 右移位赋值运算符 C >> = 2等价于C = C >> 2
    条件运算符(?:)

    条件运算符也被称为三元运算符。该运算符有3个操作数,并且需要判断布尔表达式的值。该运算符的主要是决定哪个值应该赋值给变量。

    variable x = (expression) ? value if true : value if false

    public class Test {
       public static void main(String[] args){
          int a , b;
          a = 10;
          // 如果 a 等于 1 成立,则设置 b 为 20,否则为 30
          b = (a == 1) ? 20 : 30;
          System.out.println( "Value of b is : " +  b );
     
          // 如果 a 等于 10 成立,则设置 b 为 20,否则为 30
          b = (a == 10) ? 20 : 30;
          System.out.println( "Value of b is : " + b );
       }
    }
    
    instanceof 运算符

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

    instanceof运算符使用格式如下:

    ( Object reference variable ) instanceof (class/interface type)

    如果运算符左侧变量所指的对象,是操作符右侧类或接口(class/interface)的一个对象,那么结果为真。

    下面是一个例子:

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

    Java 循环结构 - for, while 及 do...while

    顺序结构的程序语句只能被执行一次。如果您想要同样的操作执行多次,,就需要使用循环结构。

    Java中有三种主要的循环结构:

    • while 循环
    while( 布尔表达式 ) {
      //循环内容
    }
    
    • do…while 循环
    do {
           //代码语句
    }while(布尔表达式);
    
    
    • for 循环
    for(初始化; 布尔表达式; 更新) {
        //代码语句
    }
    

    示例 Test.java 文件代码:

    public class Test {
       public static void main(String args[]) {
     
          for(int x = 10; x < 20; x = x+1) {
             System.out.print("value of x : " + x );
             System.out.print("\n");
          }
       }
    }
    
    • Java 增强 for 循环

    Java 增强 for 循环语法格式如下:

    for(声明语句 : 表达式)
    {
       //代码句子
    }
    

    声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。

    表达式:表达式是要访问的数组名,或者是返回值为数组的方法。

    实例
    Test.java 文件代码:

    public class Test {
       public static void main(String args[]){
          int [] numbers = {10, 20, 30, 40, 50};
     
          for(int x : numbers ){
             System.out.print( x );
             System.out.print(",");
          }
          System.out.print("\n");
          String [] names ={"James", "Larry", "Tom", "Lacy"};
          for( String name : names ) {
             System.out.print( name );
             System.out.print(",");
          }
       }
    }
    

    编译结果:

    10,20,30,40,50,
    James,Larry,Tom,Lacy,
    
    • break 关键字
      break 主要用在循环语句或者 switch 语句中,用来跳出整个语句块。

    break 跳出最里层的循环,并且继续执行该循环下面的语句。

    语法
    break 的用法很简单,就是循环结构中的一条语句:

    break;

    实例
    Test.java 文件代码:

       public static void main(String args[]) {
          int [] numbers = {10, 20, 30, 40, 50};
     
          for(int x : numbers ) {
             // x 等于 30 时跳出循环
             if( x == 30 ) {
                break;
             }
             System.out.print( x );
             System.out.print("\n");
          }
       }
    }
    

    以上实例编译运行结果如下:

    10
    20
    
    • continue 关键字

    continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。

    在 for 循环中,continue 语句使程序立即跳转到更新语句。

    在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。

    java分支结构

    Java 有两种分支结构:

    • if 语句

    if 语句
    一个 if 语句包含一个布尔表达式和一条或多条语句。

    语法

    if(布尔表达式)
    {
    //如果布尔表达式为true将执行的语句
    }

    • switch 语句
      switch 语句
      switch 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。

    语法
    switch 语法格式如下:

    switch(expression){
    case value :
    //语句
    break; //可选
    case value :
    //语句
    break; //可选
    //你可以有任意数量的case语句
    default : //可选
    //语句
    }

    Test.java 文件代码:

    public class Test {
      public static void main(String args[]){
         //char grade = args[0].charAt(0);
         char grade = 'C';
    
         switch(grade)
         {
            case 'A' :
               System.out.println("优秀"); 
               break;
            case 'B' :
            case 'C' :
               System.out.println("良好");
               break;
            case 'D' :
               System.out.println("及格");
            case 'F' :
               System.out.println("你需要再努力努力");
               break;
            default :
               System.out.println("未知等级");
         }
         System.out.println("你的等级是 " + grade);
      }
    }
    

    java数组

    声明数组变量

    首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:

    dataType[] arrayRefVar;   // 首选的方法
    或
    dataType arrayRefVar[];  // 效果相同,但不是首选方法
    

    注意: 建议使用 dataType[] arrayRefVar 的声明风格声明数组变量。 dataType arrayRefVar[] 风格是来自 C/C++ 语言 ,在Java中采用是为了让 C/C++ 程序员能够快速理解java语言。

    实例
    下面是这两种语法的代码示例:

    double[] myList;         // 首选的方法
    或
    double myList[];         //  效果相同,但不是首选方法
    
    创建数组

    Java语言使用new操作符来创建数组,语法如下:

    arrayRefVar = new dataType[arraySize];

    上面的语法语句做了两件事:

    一、使用 dataType[arraySize] 创建了一个数组。
    二、把新创建的数组的引用赋值给变量 arrayRefVar。
    数组变量的声明,和创建数组可以用一条语句完成,如下所示:

    dataType[] arrayRefVar = new dataType[arraySize];

    处理数组

    数组的元素类型和数组的大小都是确定的,所以当处理数组元素时候,我们通常使用基本循环或者 foreach 循环。

    示例
    该实例完整地展示了如何创建、初始化和操纵数组:

    TestArray.java 文件代码:

    public class TestArray {
       public static void main(String[] args) {
          double[] myList = {1.9, 2.9, 3.4, 3.5};
     
          // 打印所有数组元素
          for (int i = 0; i < myList.length; i++) {
             System.out.println(myList[i] + " ");
          }
          // 计算所有元素的总和
          double total = 0;
          for (int i = 0; i < myList.length; i++) {
             total += myList[i];
          }
          System.out.println("Total is " + total);
          // 查找最大元素
          double max = myList[0];
          for (int i = 1; i < myList.length; i++) {
             if (myList[i] > max) max = myList[i];
          }
          System.out.println("Max is " + max);
       }
    }
    

    以上实例编译运行结果如下:

    1.9
    2.9
    3.4
    3.5
    Total is 11.7
    Max is 3.5
    
    foreach 循环

    JDK 1.5 引进了一种新的循环类型,被称为 foreach 循环或者加强型循环,它能在不使用下标的情况下遍历数组。

    示例
    该实例用来显示数组myList中的所有元素:

    TestArray.java 文件代码:

    public class TestArray {
       public static void main(String[] args) {
          double[] myList = {1.9, 2.9, 3.4, 3.5};
     
          // 打印所有数组元素
          for (double element: myList) {
             System.out.println(element);
          }
       }
    }
    
    数组作为函数的参数

    数组可以作为参数传递给方法。

    例如,下面的例子就是一个打印 int 数组中元素的方法:

    public static void printArray(int[] array) {
      for (int i = 0; i < array.length; i++) {
        System.out.print(array[i] + " ");
      }
    }
    

    下面例子调用 printArray 方法打印出 3,1,2,6,4 和 2:

    printArray(new int[]{3, 1, 2, 6, 4, 2});

    数组作为函数的返回值
    public static int[] reverse(int[] list) {
      int[] result = new int[list.length];
     
      for (int i = 0, j = result.length - 1; i < list.length; i++, j--) {
        result[j] = list[i];
      }
      return result;
    }
    

    以上实例中 result 数组作为函数的返回值。

    多维数组

    多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组,例如:

    String str[][] = new String[3][4];

    多维数组的动态初始化(以二维数组为例)
    1. 直接为每一维分配空间,格式如下:

    type arrayName = new type[arraylenght1][arraylenght2];

    type 可以为基本数据类型和复合数据类型,arraylenght1 和 arraylenght2 必须为正整数,arraylenght1 为行数,arraylenght2 为列数。

    例如:

    int a[][] = new int[2][3];

    解析:

    二维数组 a 可以看成一个两行三列的数组。

    1. 从最高维开始,分别为每一维分配空间,例如:
    String s[][] = new String[2][];
    s[0] = new String[2];
    s[1] = new String[3];
    s[0][0] = new String("Good");
    s[0][1] = new String("Luck");
    s[1][0] = new String("to");
    s[1][1] = new String("you");
    s[1][2] = new String("!");
    

    解析:

    s[0]=new String[2] 和 s[1]=new String[3] 是为最高维分配引用空间,也就是为最高维限制其能保存数据的最长的长度,然后再为其每个数组元素单独分配空间 s0=new String("Good") 等操作。

    多维数组的引用(以二维数组为例)
    对二维数组中的每个元素,引用方式为 arrayName[index1][index2],例如:

    num[1][0];

    Arrays 类

    java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。

    具有以下功能:

    给数组赋值:通过 fill 方法。
    对数组排序:通过 sort 方法,按升序。
    比较数组:通过 equals 方法比较数组中元素值是否相等。
    查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。

    Java 方法

    方法的命名规则

    1.方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。

    2.下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。一个典型的模式是:test<MethodUnderTest>_<state>,例如 testPop_emptyStack。

    方法的定义
    修饰符 返回值类型 方法名(参数类型 参数名){
        ...
        方法体
        ...
        return 返回值;
    }
    

    方法包含一个方法头和一个方法体。下面是一个方法的所有部分:

    • 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
    • 返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void
    • 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
    • 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
    • 方法体:方法体包含具体的语句,定义该方法的功能。
    image

    如:

    public static int age(int birthday){...}

    参数可以有多个:

    static float interest(float principal, int year){...}

    注意: 在一些其它语言中方法指过程和函数。一个返回非void类型返回值的方法称为函数;一个返回void类型返回值的方法叫做过程。

    方法调用

    Java 支持两种调用方法的方式,根据方法是否返回值来选择。

    当程序调用一个方法时,程序的控制权交给了被调用的方法。当被调用方法的返回语句执行或者到达方法体闭括号时候交还控制权给程序。

    当方法返回一个值的时候,方法调用通常被当做一个值。例如:

    int larger = max(30, 40);

    如果方法返回值是void,方法调用一定是一条语句。例如,方法
    println返回void。下面的调用是个语句:

    System.out.println("欢迎访问菜鸟教程!");

    方法的重载

    上面使用的max方法仅仅适用于int型数据。但如果你想得到两个浮点类型数据的最大值呢?

    解决方法是创建另一个有相同名字但参数不同的方法,如下面代码所示:

    public static double max(double num1, double num2) {
      if (num1 > num2)
        return num1;
      else
        return num2;
    }
    

    如果你调用max方法时传递的是int型参数,则 int型参数的max方法就会被调用;

    如果传递的是double型参数,则double类型的max方法体会被调用,这叫做方法重载;

    就是说一个类的两个方法拥有相同的名字,但是有不同的参数列表。

    变量作用域

    变量的范围是程序中该变量可以被引用的部分。
    方法内定义的变量被称为局部变量。
    局部变量的作用范围从声明开始,直到包含它的块结束。
    局部变量必须声明才可以使用。
    方法的参数范围涵盖整个方法。参数实际上是一个局部变量。
    for循环的初始化部分声明的变量,其作用范围在整个循环。
    但循环体内声明的变量其适用范围是从它声明到循环体结束。它包含如下所示的变量声明:


    image

    你可以在一个方法里,不同的非嵌套块中多次声明一个具有相同的名称局部变量,但你不能在嵌套块内两次声明局部变量。

    命令行参数的使用

    有时候你希望运行一个程序时候再传递给它消息。这要靠传递命令行参数给main()函数实现

    命令行参数是在执行程序时候紧跟在程序名字后面的信息。

    实例
    下面的程序打印所有的命令行参数:

    CommandLine.java 文件代码:

    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
    
    构造方法

    当一个对象被创建时候,构造方法用来初始化该对象。构造方法和它所在类的名字相同,但构造方法没有返回值。

    通常会使用构造方法给一个类的实例变量赋初值,或者执行其它必要的步骤来创建一个完整的对象。

    不管你与否自定义构造方法,所有的类都有构造方法,因为Java自动提供了一个默认构造方法,它把所有成员初始化为0。

    一旦你定义了自己的构造方法,默认构造方法就会失效。

    实例
    下面是一个使用构造方法的例子:

    // 一个简单的构造函数
    class MyClass {
      int x;
     
      // 以下是构造函数
      MyClass() {
        x = 10;
      }
    }
    

    你可以像下面这样调用构造方法来初始化一个对象:

    ConsDemo.java 文件代码:

    public class ConsDemo {
       public static void main(String args[]) {
          MyClass t1 = new MyClass();
          MyClass t2 = new MyClass();
          System.out.println(t1.x + " " + t2.x);
       }
    }
    

    大多时候需要一个有参数的构造方法。

    实例
    下面是一个使用构造方法的例子:

    // 一个简单的构造函数
    class MyClass {
      int x;
     
      // 以下是构造函数
      MyClass(int i ) {
        x = i;
      }
    }
    

    你可以像下面这样调用构造方法来初始化一个对象:

    ConsDemo.java 文件代码:

    public class ConsDemo {
      public static void main(String args[]) {
        MyClass t1 = new MyClass( 10 );
        MyClass t2 = new MyClass( 20 );
        System.out.println(t1.x + " " + t2.x);
      }
    }
    

    运行结果如下:

    10 20

    可变参数

    JDK 1.5 开始,Java支持传递同类型的可变参数给一个方法。

    方法的可变参数的声明如下所示:

    typeName... parameterName

    在方法声明中,在指定参数类型后加一个省略号(...) 。

    一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。

    实例
    VarargsDemo.java 文件代码:

    public class VarargsDemo {
        public static void main(String args[]) {
            // 调用可变参数的方法
            printMax(34, 3, 3, 2, 56.5);
            printMax(new double[]{1, 2, 3});
        }
     
        public static void printMax( double... numbers) {
            if (numbers.length == 0) {
                System.out.println("No argument passed");
                return;
            }
     
            double result = numbers[0];
     
            for (int i = 1; i <  numbers.length; i++){
                if (numbers[i] >  result) {
                    result = numbers[i];
                }
            }
            System.out.println("The max value is " + result);
        }
    }
    

    以上实例编译运行结果如下:

    The max value is 56.5
    The max value is 3.0
    

    Java 重写(Override)与重载(Overload)

    • 重写

    重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

    重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

    TestDog.java 文件代码:

    class Animal{
       public void move(){
          System.out.println("动物可以移动");
       }
    }
     
    class Dog extends Animal{
       public void move(){
          System.out.println("狗可以跑和走");
       }
    }
     
    public class TestDog{
       public static void main(String args[]){
          Animal a = new Animal(); // Animal 对象
          Animal b = new Dog(); // Dog 对象
     
          a.move();// 执行 Animal 类的方法
     
          b.move();//执行 Dog 类的方法
       }
    }
    

    以上实例编译运行结果如下:

    动物可以移动
    狗可以跑和走
    
    • 重载(Overload)

    重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

    每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

    最常用的地方就是构造器的重载。

    重载规则

    被重载的方法必须改变参数列表(参数个数或类型或顺序不一样);
    被重载的方法可以改变返回类型;
    被重载的方法可以改变访问修饰符;
    被重载的方法可以声明新的或更广的检查异常;
    方法能够在同一个类中或者在一个子类中被重载。
    无法以返回值类型作为重载函数的区分标准。
    实例
    Overloading.java 文件代码:

    public class Overloading {
        public int test(){
            System.out.println("test1");
            return 1;
        }
     
        public void test(int a){
            System.out.println("test2");
        }   
     
        //以下两个参数类型顺序不同
        public String test(int a,String s){
            System.out.println("test3");
            return "returntest3";
        }   
     
        public String test(String s,int a){
            System.out.println("test4");
            return "returntest4";
        }   
     
        public static void main(String[] args){
            Overloading o = new Overloading();
            System.out.println(o.test());
            o.test(1);
            System.out.println(o.test(1,"test3"));
            System.out.println(o.test("test4",1));
        }
    }
    

    Java 多态

    多态是同一个行为具有多个不同表现形式或形态的能力。(按下F1键在不同的地方会有不同的反应)
    当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

    多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

    相关文章

      网友评论

        本文标题:java学习笔记

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