zoukankan      html  css  js  c++  java
  • Java学习笔记(2)

    ●向上转型,向下转型,

    向上转型,就是子类转型成父类。如: 麻雀是鸟, 这是非强制的说法;

    向下转型,就是父类转型成子类。如: 鸟是麻雀, 这是强制的说法;

    Java中不被static修饰的方法,

    如果去掉mul()方法的static修饰符, 第六行会提示: Cannot make a static reference to the non-static method mul(int) from the type

    demo

    1:没有static修饰的方法,在调用的时候需要先创造对象 类名 对象名=new 类名(); 对象名.方法名(); 2:static修饰的方法,在调用的时候直接调用 类名.方法名(); 也就是说: 没有static修饰的,它们在生成的时候,就属于对象。 有static修饰的,它们在生成的时候,就属于类。 main方法是java自带的,我们创建它的时候,就已经注定了它的必然性——静态方法。 在静态方法中,只能访问静态的变量,还有静态的其他方法。

    static方法只能访问static方法,非static方法可以访问static方法,

    原因:

    static是属于类的,而非static的普通方法是属于对象的。

    属于类的静态方法可以在对象不存在的时候就能访问到,而普通方法必须先new一个对象才能用这个对象访问。

    为什么main()方法是static?

    因为在程序开始执行时必须调用main()

    我们知道,在C/C++当中,这个main方法并不是属于某一个类的,它是一个全局的方法,所以当我们执行的时候,c++编译器很容易的就能找到这个main方法,然而当我们执行一个java程序的时候,因为java都是以类作为程序的组织单元,当我们要执行的时候,我们并不知道这个main方法会放到哪个类当中,也不知道是否是要产生类的一个对象,为了解决程序的运行问题,我们将这个main方法定义为static,这样的话,当我们在执行一个java代码的时候,我们在命令提示符中写:java PointPoint为一个类),解释器就会在Point这个类当中,去调用这个静态的main方法,而不需要产生Point这个类的对象,当我们加载Point这个类的时候,那么main方法也被加载了,作为我们java程序的一个入口。

    JavaBean的解释

    JavaBean是符合某种规范的Java组件,也就是一个可以重复使用的Java, 这个类创建的一个对象称做一个Bean。这个类具有如下特点:

    1. 创建JavaBean类时必须带有包名, 且必须实现序列化接口;

    Java"对象序列化"能让你将一个实现了Serializable接口的对象转换成一组Byte,这样日后要用这个对象时候,你就能把这些byte数据恢复出来,并据此重新构建那个对象了。

    2. 必须具有一个访问属性为public的无参构造函数;

    3. 类中所有的属性都必须定义为私有的, 所有方法都必须定义为公有的;

    4. 私有化的属性必须通过public类型的方法暴露给其他程序,并且方法的命名也必须遵守一定的命名规范, 具体来说:

    ① 如果属性名是xxx,那么为了更改或获取属性,在类中可以使用两个public方法:

    getXXX():用来获取属性xxx

    setXXX():用来修改属性xxx.

    ② 对于boolean类型的成员变量,允许使用"is"代替上面的"get""set", 如。

     

    JavaBean的作用:

    JavaBean可以非常好地实现控制逻辑、业务逻辑、表示层之间的分离,从而大大降低了它们之间的耦合度。

     

    • 有关内省/反射(reflection)

    内省:把一类中需要进行设置和获得的属性访问权限设置为private(私有的)让外部的使用者看不见摸不着,而通过public(共有的)setget方法来对其属性的值来进行设置和获得,而内部的操作具体是怎样的?外界使用的人不用知道,这就称为内省。

    JavaBean案例:

    package JavaBean;

    import java.io.Serializable;

    public class JavaBeanDemo implements Serializable { // 实现了Serializable接口

        public JavaBeanDemo() {

        } // 无参的构造方法

        private int id; // 私有属性Id

        private String name; // 私有属性name

        public int getId() {

            return Id;

        }

        public void setId(int id) { // set()方法

            this.id = id;

        }

        public String getName() { // get()方法

            return name;

        }

        public void setName(String name) {

            this.name = name;

        }

    }

    JavaBean更实际的案例:

    假如有人要用Java实现一个单向链表类,可能会这样写:

    // 编译成 java-int-list_1.0.jar

    public final class JavaIntList {

    static class Node {

    public Node next;

    public int value;

    }

    public Node head;

    public int size;

    }

    上述实现为了能够快速获取链表的大小,把链表大小缓存在size变量中。用法如下:

    JavaIntList myList = new JavaIntList();

    System.out.println(myList.size);

    JavaIntList的作者很满意,于是开源了java-int-list库的1.0版。文件名是java-int-list_1.0.jar。发布后,吸引了许多用户来使用java-int-list_1.0.jar。
    有一天,作者决定要节省内存,不要缓存size变量了,把代码改成这样:

    // 编译成 java-int-list_2.0.jar

    public final class JavaIntList {

    static final class Node {

    public Node next;

    public int value;

    }

    public Node head;

    public int getSize() {

    Node n = head;

    int i = 0;

    while (n != null) {

    n = n.next;

    i++;

    }

    return i;

    }

    }

    然后发布了2.0版:java-int-list_2.0.jar。发布后,原有java-int-list_1.0.jar的用户纷纷升级版本到2.0。这些用户一升级,就发现自己的程序全部坏掉了,说是找不到什么size变量。于是这些用户就把作者暴打一顿,再也不敢用java-int-list库了。

    这个故事告诉我们,如果不想被暴打致死,你就必须保持向后兼容性。太阳公司在设计Java语言时,也懂得这个道理。所以Java标准库中,绝对不会出现public int size这样的代码,而一定会一开始就写成:

    private int size;

    public int getSize() { return size; }

    让用户一开始就使用getSize,以便有朝一日修改getSize实现时,不破坏向后兼容性。这种public int getSize() { return size; }的惯用手法,就是Java Bean。 

     

     

    构造函数的访问属性

    public 常用

    private 单例

    static 不可以(Java中静态的东西都是属于类的,为类服务,构造函数是为了初始化对象,为对象服务)

     

    ●如果子类没有重写父类的方法,那么supper.父类方法()this.父类方法()的作用是一样的。

    重写父类的方法以后, super用来调用父类的方法,this调用子类重写的方法。

    属性的情况是一样的。 

    public class F{//定义父类

    public void s(){//定义父类方法s

    }

    }

    public class K extends F{//定义子类K,继承父类F

    public void s(){//定义子类方法s,覆盖父类s

    }

    public void k2(){

    super.s();//通过super,指明调用父类的方法s

    this.s();//通过this,指明调用当前类的方法s

    }

    }

     

    superthis的异同:

    1)super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句)

    2)this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句)

    3)super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)

    4)this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)

    5)调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。

    6)super()this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它方法。

    7)super()this()均需放在构造方法内第一行。

    8)尽管可以用this调用一个构造器,但却不能调用两个。

    9)thissuper不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。

    10)this()super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。

    11)从本质上讲,this是一个指向当前类的对象的指针, 然而super是一个Java关键字。

     

    ●程序绑定的概念:

    绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定.

     

    静态绑定:

    在程序执行前方法已经被绑定(也就是说在编译过程中就已经知道这个方法到底是哪个类中的方法),此时由编译器或其它连接程序实现。例如:C

    针对java简单的可以理解为程序编译期的绑定;这里特别说明一点,java当中的方法只有finalstaticprivate和构造方法是前期绑定

     

    动态绑定:

    后期绑定:在运行时根据具体对象的类型进行绑定。

    若一种语言实现了后期绑定,同时必须提供一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。不同的语言对后期绑定的实现方法是有所区别的。但我们至少可以这样认为:它们都要在对象中安插某些特殊类型的信息。

    动态绑定的过程:

    虚拟机提取对象的实际类型的方法表;

    虚拟机搜索方法签名;

    调用方法。 

    Java中的变量都是静态绑定的,方法的话只有staticfinal(所有private默认是final)是静态绑定的.

    :类的private方法会隐式地被指定为final方法。

     

    ●实例变量 & 静态变量

    实例变量必须创建对象后才可以通过这个对象来使用;

    静态变量则可以直接使用类名来引用。 

     

    ● 类只加载一次

    如果不是有特殊用途,每个类在虚拟机中被加载并且只加载一次。

    什么时候会加载类?

    有三种情况

    1.创建对象:new StaticCode();

    2.使用类中的静态成员:StaticCode.num=9; StaticCode.show();

    3.在命令行中运行:java StaticCodeDemo

     

    ●静态代码块、构造代码块和构造函数的区别

    静态代码块:用于给类初始化,类加载时就会被加载执行,只加载一次。

    构造代码块:用于给对象初始化的。只要建立对象该部分就会被执行,且优先于构造函数。

    ※ 直接在类中定义且没有加static关键字的代码块称为{}构造代码块。

    构造函数: 给对应对象初始化的,建立对象时,选择相应的构造函数初始化对象。 

    //静态代码块案例:

    package demo;

     

    class Parent {

        static String name = "hello";

        {

            System.out.println("parent block");

        }

        static {

            System.out.println("parent static block");

        }

     

        public Parent() {

            System.out.println("parent constructor");

        }

    }

     

    class Child extends Parent {

        static String childName = "hello";

        {

            System.out.println("child block");

        }

        static {

            System.out.println("child static block");

        }

     

        public Child() {

            System.out.println("child constructor");

        }

    }

     

    public class StaticIniBlockOrderTest {

     

        public static void main(String[] args) {

            new Child();

        }

    }

     

    parent static block

    child static block

    parent block

    parent constructor

    child block

    child constructor

    对象的初始化顺序:首先执行父类静态的内容,

    父类静态的内容执行完毕后,接着去执行子类的静态的内容,

    当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,

    父类的非静态代码块执行完毕,接着执行父类的构造方法;

    父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。

    总之一句话,静态代码块内容先执行(父类静态的内容执行完毕后,接着去执行子类的静态的内容),接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。 

    再如:

    class Code{
    
        {
    
          System.out.println("Code的构造块");
    
        }
    

     

    
    										static{
    
            System.out.println("Code的静态代码块");
    
            }
    

     

    
    										public Code(){
    
            System.out.println("Code的构造方法");
    
            }
    
        }
    

     

     

    public class CodeBlock03{
    
         {
    
          System.out.println("CodeBlock03的构造块");    
    
         }
    

     

    
    										static{
    
            System.out.println("CodeBlock03的静态代码块");
    
            }
    

     

    
    										public CodeBlock03(){
    
                 System.out.println("CodeBlock03的构造方法");
    
                }
    

     

    
    										public static void main(String[] args){
    
                System.out.println("CodeBlock03的主方法");
    
    
    										new Code();
    
    
    										new Code();
    
    
    										new CodeBlock03();
    
    
    										new CodeBlock03();
    
              }
    
        }
    
    /*
    
    CodeBlock03的静态代码块
    
    CodeBlock03的主方法
    
    Code的静态代码块
    
    Code的构造块
    
    Code的构造方法
    
    Code的构造块
    
    Code的构造方法
    
    CodeBlock03的构造块
    
    CodeBlock03的构造方法
    
    CodeBlock03的构造块
    
    CodeBlock03的构造方法
    
    */

    ●为什么要用父类引用指向子类对象?

    Shape s = new Circle(5,6,4);

    可以用这几个关键词来概括:多态、动态链接、向上转型

     

    例如父类person有子类menwomen, 现在要写一个对象数组,其元素包括子类men类型和women类型的, 我们写成:

    person[] a=new person[]{new men("小明"),new women("小红")};

    这其实就是一个父类引用指向子类对象, 如果用子类是不行的.

    ● 抽象类和接口的异同

    相同点

    都不能被直接实例化,但可以定义抽象类或接口类型的引用变量,并且可以通过继承实现其抽象方法。

    都是面向抽象编程的技术基础,实现了诸多的设计模式。

     

    不同点

    抽象类不能实现多继承;接口支持多继承。

    抽象类既可以定义抽象方法,也可以定义非抽象方法;接口只能定义抽象方法。

    抽象类可以有普通数据成员,接口不可以有普通数据成员(只能有全局常量)

     

    形象比喻

    接口是对动作的抽象,抽象类是对根源的抽象。

    抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人,女人,这两个类(如果是类的话……),他们的抽象类是人。说明,他们都是人。

    人可以吃东西,狗也可以吃东西,你可以把"吃东西"定义成一个接口,然后让这些类去实现它.

    所以,在高级语言上(不包括C++和Python),一个类只能继承一个类(抽象类)(正如人不可能同时是生物和非生物),但是可以实现多个接口(吃饭接口、走路接口)

     

    接口函数就是某个模块写的主要用来给其它模块调用的函数。

    简单的说接口函数就是一个类中的公有函数, 它提供程序与类的私有成员之间的接口, 一个对象可以通过它来访问类私有成员.

    例如:

    SendMessage(...); 是一个发消息的函数,我们无须知道它是怎么实现的,只需要知道他能实现向某个东西发送消息即可.

     

    举个例子,搅拌机是一个类,把苹果,橘子,梨等水果(参数)放进去(发送消息)就出来果汁(结果,返回值).

    class 搅拌机

    {

    private:

        零件;

    public:

        饮料 搅拌(水果); // 这个就是接口

    };

    int main(void)

    {

        搅拌机 A = new 搅拌机;

        饮料 苹果汁 = A-> 搅拌(一个黄元帅,两个红富士);// 调用接口

        delete A;

        return 0;

    }

     

    这就是接口,接口对应的就是实现。

     

    每一个*.class的文件都对应一个类或则接口,*.class文件是JVM真正能读懂的文件格式。

     

    //下面的不同点暂时不用深入

    接口是一组行为规范;抽象类是一个不完全的类,着重族的概念。

    接口可以用于支持回调;抽象类不能实现回调,因为继承不支持。

    接口只包含方法、属性、索引器、事件的签名,但不能定义字段和包含实现的方法;抽象类可以定义字段、属性、包含有实现的方法。

    接口可以作用于值类型和引用类型;抽象类只能作用于引用类型。例如,Struct就可以继承接口,而不能继承类。

    //抽象类(abstract class)的定义方式如下:

    public abstract class AbstractClass //抽象类里面至少有一个抽象方法

    {

        public int t; //普通数据成员

        public abstract void method1(); //抽象方法,抽象类的子类在类中必须实现抽象类中的抽象方法

        public abstract void method2();

        public void method3(); //非抽象方法

        public int method4 (){

        //抽象类中可以赋予非抽象方法方法的默认行为,即方法的具体实现

        }

    }

       

    //接口(interface)的定义方式如下:

    public interface Interface

    {

        static final int i; //接口中不能有普通数据成员,只能够有静态的不能被修改的数据成员,static表示全局,final表示不可修改,可以不用static final 修饰,因为会隐式的声明为staticfinal

        public void method1(); //接口中的方法一定是抽象方法,所以不用abstract修饰

        public void method2(); //接口中不能赋予方法的默认行为,即不能有方法的具体实现

    }

    ● 理解"一个类可以实现多个接口,但一个类不能实现多继承"

    一个类可以实现多个接口: 接口成员均为全局常量和抽象方法, 即使不同接口存在同名抽象方法,并不会造成方法一个类不能实现多继承: 如果父类中存在同名但不同实现非抽象方法,多继承就造成了混乱

    JavaString类的内存分配

    1

    物理的内存是线性结构,并不存在拥有不同功能的不同区域。

    编译器(或者JVM)为了更高效地处理数据,会用不同的算法把内存分为各种区域,不同的区域拥有各自的特性,Java中,内存可以分为栈,堆,静态域和常量池等。(可能有不同的叫法,但逻辑是一致的)

     

    2

    不同内存区域的功能和特点:

    栈区:存放局部变量(变量名,对象的引用等)特点:内存随着函数的调用而开辟,随着函数调用结束而释放。

    堆区:存放对象(也就是new出来的东西)特点:可以跨函数使用,每个对象有自己对应的存储空间。

    静态域:存放在对象中用static定义的静态成员。

    常量池:存放常量。(常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。)

     

    3

    定义String的方法:

    1,String str1 = "hello";

    2,String str2 = new String("hello");

    第一种方法:引用str1被存放在栈区,字符串常量"hello"被存放在常量池,引用str1指向了常量池中的"hello"(str1中的存放了常量池中"hello"的地址)

    第二种方法:引用str2被存放在栈区,同时在堆区开辟一块内存用于存放一个新的String类型对象。(同上,str2指向了堆区新开辟的String类型的对象)

    如下图:

    Java中String类的内存分配

     

    4

    这两种方法的区别是什么?

    第一种:常量池的字符串常量,不能重复出现,也就是说,在定义多个常量时,编译器先去常量池查找该常量是否已经存在,如果不存在,则在常量池创建一个新的字符串常量;如果该常量已经存在,那么新创建的String类型引用指向常量池中已经存在的值相同的字符串常量,也就是说这是不在常量池开辟新的内存。

    String str1 = "hello";

    String str2 = "hello";

    示意图如图1

    第二种:在堆中创建新的内存空间,不考虑该String类型对象的值是否已经存在。换句话说:不管它的 只是多少,第二种方法的这个操作已经会产生的结果是:在堆区开辟一块新的内存,用来存放新定义的String类型的对象。

    String str1 = new String("hello");

    String str2 = new String("hello");

    示意图如果2

    Java中String类的内存分配

    Java中String类的内存分配

     

    5

    下面用代码来测试:

    public class Test

    {

    public static void main(String[] args)

    {

    String str1 = "hello";

    String str2 = "hello";

    System.out.println(str1 == str2);//true

    System.out.println(str1.equals(str2));//true

     

    String str3 = new String("hello");

    String str4 = new String("hello");

    System.out.println(str3 == str4);//false

    System.out.println(str3.equals(str4));//true

    System.out.println(str1 == str3);//false

    System.out.println(str2.equals(str3));//true

    //这里涉及到==equals方法的区别,请看我的另一篇文章:《Java中,equals ==的渊》http://jingyan.baidu.com/article/f96699bbc9d6ae894e3c1b81.html

    }

    }

    ●如果在创建类的时候没有声明要继承的类 那么java就默认 将它继承于Object

    public class A{

    /*Code*/

    }

     

    public class A extends java.lang.Object{

    /*Code*/

    }

    以上两种的等价的public class Test // Object类继承

    Object中有3个非常重要的方法

    hashcode(), toString(), equals()

    Sun都是建议我们写自己的类的时候,最好都重写上述3个方法

     

     

    ●所有类都从Object类继承。

    如果自定义的类没有覆盖toString方法,则对象在调用toString方法时用的是ObjecttoString方法,返回的是:包名.类名@此对象哈希码的无符号十六进制表示。相当于:

    getClass().getName() + '@' + Integer.toHexString(hashCode())

     

    如果equals没有被覆盖,作用则是判断两个对象是否相同。

     

    如果hashCode()没有覆盖,返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。

     

     

     

    toString方法

     

    hashCode( )

    1)hashCode:创建的对象在堆内存中的地址值 经过一系列非常复杂的算法转化而来的int类型的数值,它是一种用于查找的索引值(一对一或多对一的关系),对开发来说无意义。

    2)如果两个对象相等话,

        第①个条件:equals返回的结果必须是true

        第②个条件:必须要有相等的hashCode

    3)如果两个对象不相等,则hashCode值一定不等

    4)判断对象是否相等的时候,必须要重写equalshashCode

     

    Java不能像C/C++一样直接查看内存地址, 但可借助OllyDbg, Cheat Engine等工具

     

    c17164是12677476的十六进制

     

    equals方法

    (1)s1 == s2为true,因为s1s2都是字符串字面值"nihao"的引用,指向同一块地址,所以相等。

    (2)s1 == s3为false,是因为通过new产生的对象在堆中,s3是堆中对象的引用,而是s1是指向字符串字面值"nihao"的引用,地址不同所以不相等。

     

    arraycopy(),

    System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制。其函数原型是: public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

    src:源数组;

    srcPos:源数组要复制的起始位置;

    dest:目的数组;

    destPos:目的数组放置的起始位置;

    length:复制的长度。 

     

    Javastringconcat方法和+的区别concat()和+都是String类的方法

    都可以将2个字符串拼接到一块,这一点2这功能相同。

     

    但是 + 还可以将 字符串与非字符串(比如数字),拼接在一起,成为字符串。

     

    • concatenate [kən'kætɪneɪt] vt.把 (一系列事件、事情等)联系起来;
    • "1"+"2"结果是"12"; '1'+'2'结果是49+50=99

     

    ●字符串池

    Java虚拟机有一个字符串池,保存着几乎所有的字符串对象。

    字符串表达式总是指向字符串池 中的一个对象。

    使用new操作创建的字符串对象不指向字符串池中的对象, 但是可以使用intern方法使其指向字符串池中的对象.

    (注:如果池中已经有相同的 字符串--使用equals方法确定,则直接返回池中的字符串,否则先将字符串添加到池中,再返回)。池中两个相等的字符串如果使用"=="来比较将返回 真。

     

    ==和equals

    ==是判断两个变量或实例是不是指向同一个内存空间

    equals是判断两个变量或实例所指向的内存空间的值是不是相同

     

    ●区别下面两种说法

    while(in.readLine()!=null){

    String aa=in.readLine();

    }

    //第一个在读到while(in.readLine()!=null)的时候,如果有数据,那么执行String aa=in,readLine()的时候程序会继续往下读,也就是第一个while里面的读入被抛弃了,如果程序读入的只有是一行的话,那么这行就不会读入!!

     

    while(true){

    String aa=in.readLine();

    }

    因此while(true) 是一个无限循环,因为表达式的值一直为真。

     

    为了跳出循环,循环体内部要用break语句来跳出。

    例如,可以在循环体内部用if来判断,if(x==5)break;

     

    Java的正则表达式的运用

    Java使用正则表达式需要涉及到PatternMatcher

    Pattern和Matcher之间的关系就好比Pattern是做模具的师傅,Pattern将模具(正则表达)做好之后,指派一个小工(matcher)去匹配,matcher要做的就是原材料(即要被匹配的源字符串)和模具(即Pattern中的正则表达式)配对、比较。

     

    ※ 回想学KMP算法时候学到的Pattern(模式串)

     

    matcher.find()matcher.matches()的区别?

    find是部分匹配,matches是全部匹配

     

    Pattern的静态方法matcher()的作用?

    Matcher matcher = pattern.mathcer(scanner.nextLine())

    Pattern对象将会使用matcher()方法来生成一个Matcher实例,接着便可以使用这个 Matcher实例(以编译的正则表达式为基础)对目标字符串进行匹配工作,多个Matcher是可以共用一个Pattern对象的。

     

    StringBuilder

    public StringBuilder delete(int start, int end)

    参数

    start -- This is the beginning index, inclusive.

    end -- This is the ending index, exclusive.

     

    ArrayList的元素可以是……

    //下面ArrayList的元素可以是

        ArrayList list=new ArrayList();

        list.add("");

        list.add("");

        list.add(0, "");

        list.add(1, "");

        System.out.println(list);

        System.out.println(list.indexOf(""));

        System.out.println(list.get(2));

        

        ArrayList list2=new ArrayList();

        list2.add(new String(""));

        list2.add(new String(""));

        list2.add(0, new String(""));

        list2.add(1, new String(""));

        System.out.println(list);

        System.out.println(list.indexOf(""));

        System.out.println(list.get(2));

    [, , , ]

    3

    [, , , ]

    3

     

  • 相关阅读:
    Mysql查询语句,select,inner/left/right join on,group by.....[例题及答案]
    Java IO实现文件(及文件夹)的复制 原创代码【精】
    [精华帖]Java接口怎么定义?如何使用?【实例讲解】
    Java面向对象中this关键字详解 意义+实例讲解【hot】
    linux系统编程之进程(三):进程复制fork,孤儿进程,僵尸进程
    linux系统编程之进程(二):进程生命周期与PCB(进程控制块)
    linux系统编程之进程(一):进程与程序
    linux系统编程之文件与IO(八):文件描述符相关操作-dup,dup2,fcntl
    linux系统编程之文件与IO(七):时间函数小结
    linux系统编程之文件与IO(六):实现ls -l功能
  • 原文地址:https://www.cnblogs.com/ArrozZhu/p/8382326.html
Copyright © 2011-2022 走看看