ArrayList无参构初始化

JavaArrayList无参构造器初始化过程详解

ArrayList无参构初始化

    @Test
    public void testArrayList(){
        ArrayList<Integer> arrayList = new ArrayList<>();
        ArrayList<Integer> list = new ArrayList<>();
    }

先来到:ClassLoader这个类加载器:

    private void checkPackageAccess(Class<?> cls, ProtectionDomain pd) {
        final SecurityManager sm = System.getSecurityManager();
/*SecurityManager方法在System类:
    public static SecurityManager getSecurityManager() {
        return security;----->    private static volatile SecurityManager security = null;
    }

*/
        if (sm != null) {//发现这个为null,那么就跳过了
            if (ReflectUtil.isNonPublicProxyClass(cls)) {
                for (Class<?> intf: cls.getInterfaces()) {
                    checkPackageAccess(intf, pd);
                }
                return;
            }

            final String name = cls.getName();
            final int i = name.lastIndexOf('.');
            if (i != -1) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        sm.checkPackageAccess(name.substring(0, i));
                        return null;
                    }
                }, new AccessControlContext(new ProtectionDomain[] {pd}));
            }
        }
    }

上面的操作应该是看看有没有类对象被初始化过了

因为sm是null于是直接skip了,回到ArrayList的初始化进程里了。

正片:

1、来new一个模拟一下

List<Integer> arrayList = new ArrayList<>();

2、进入到ArrayList无参构造器:

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

3、进入到AbstractList构造器

protected AbstractList() {
}

4、进入到AbstractCollection构造器

protected AbstractCollection() {
}

5、来到Object

在Object类中没有看到构造器,为什么?其实不是没有构造器,而是没看到构造器函数,因为默认无参构造器可以不写。

6、这里初始化object后就回到AbstractCollection类的无参构造器函数进行实例化

7、回到AbstractList对transient修饰的modCount进行初始化,再完成AbstractList的实例化。

8、回到ArrayList对this.elementData对象初始化,然后就初始化ArrayList对象。

对于另一个ArrayList对象就直接不走类加载器了,直接和变量arrayList的2-8步一样。

建立一个继承体系,List是基ArrayList和LinkedList是其派生。并且编写实现下述函数并达到如下效果。 ostream& operator << (ostream&os, const List&rhs); 做一个流输出运算符重载,其第二个数是List的常引用型。我们知道子的对象天生可以作为父型使用,因此 ArrayList a; LinkedList b; operator << (cout,a); operator << (cout,b); 这上面的调用显然都是合法的。但是现在要求实现如下效果:第3行的函数执行的是适合ArrayList输出的代码,而第4行执行的是适合LinkedList输出的代码。即,虽然调用的函数一样,但需要根据当时的实型选择合适的实现。相当于对非成员函数做到动态绑定。 2. 相关知识 前面说过,虚函数可以实现动态绑定。也就是: class List{ public: virtual void disp(ostream&os)const; }; class ArrayList : public List{ public: void disp(ostream&os)const{/*这里是ArrayList的实现*/} } class LinkedList : public List{ public: void disp(ostream&os)const{/*这里是LinkedList的实现*/} } List *p = new ArrayList; p->disp(cout);//此时调用的是ArrayList的disp函数 delete p; p = new LinkedList; p->disp(cout);//此时调用的是LinkedList的disp函数 delete p; 如果是非成员函数,能不能实现似效果呢?即 ostream& operator << (ostream&os, const List&rhs); ostream& operator << (ostream&os, const ArrayList&rhs); ostream& operator << (ostream&os, const LinkedList&rhs); List *p = new ArrayList; cout<<*p<<endl;//此时希望调用的是operator<<(ostream,ArrayList&) delete p; p = new LinkedList; cout<<*p<<endl;//此时希望调用的是operator<<(ostream,LinkedList&) delete p; 遗憾的是,非成员函数不具备这样的功能。对于上述流输出运算符调用而言,它的实会被看作是List型,因此只会调用上文中的第一个重载函数。而不会根据p实际指向的型动态调用其他流输出重载函数。 如何令非成员函数也体现出动态绑定的特性呢?答案是通过成员函数,而不是通过函数重载。例如,可以这样实现流输出运算符重载: ostream& operator << (ostream&os,const List&rhs){ rhs.disp(os); return os; } /************************************************** *这里不再需要实现 * ostream& operator << (ostream&os, const List&rhs); *和 * ostream& operator << (ostream&os, const List&rhs); *等函数 *****************************************************/ 3. 编程要求 本关共有8个文件。其中List.h定义了List及其成员函数。ListOp.h和ListOp.cpp定义了与List相关的运算符重载。ArrayList.h和ArrayList.cpp定义了ArrayList及其成员函数。LinkedList.h和LinkedList.cpp定义了LinkedList及其成员函数。main.cpp定义了主函数。 用户的任务是编写List.h、ArrayList.cpp和LinkedList.cpp文件,以使得main.cpp正确运行。 List.h内容如下: #ifndef _LIST_H_ #define _LIST_H_ #include <iostream> using std::ostream; class List{ protected: int size; public: //兼具默认构造函数和功能构造函数 List(int s=0):size(s){} //拷贝构造函数 List(const List&rhs):size(rhs.size){} /*以下为虚函数*/ //作为继承的基的析构函数一定要是虚的 virtual ~List(){} //普通的非虚函数 int getSize()const{return size;} /*以下为纯虚函数,即没有实现*/ virtual void insert(int pos,int value)=0; virtual void remove(int pos)=0; virtual int at(int pos)const=0; virtual void modify(int pos,int newValue)=0; /*你的工作在这里:此处设计disp函数*/ }; #endif // _LIST_H_ ListOp.h内容如下: #include "List.h" //流输出运算符重载声明 ostream operator << (ostream& os,const List& rhs); ListOp.cpp内容如下: #include "List.h" #include <iostream> using std::ostream; ostream& operator << (ostream&os, const List&rhs){ rhs.disp(os); return os; } ArrayList.h的内容如下: #ifndef _ARRAYLIST_H_ #define _ARRAYLIST_H_ #include "List.h" class ArrayList : public List{ private: int *data; //真正保存数据的地方 int capacity;//容量 public: //默认构造函数,构造一个逻辑为空的顺序表 ArrayList(); //拷贝构造函数,构造一个逻辑上与数内容相同的顺序表 ArrayList(const ArrayList&rhs); //原生数组构造函数,构造一个内容与给定数组相同的顺序表 ArrayList(int const a[],int n); //填充构造函数,构造一个内容为n个value的顺序表 ArrayList(int n,int value); //析构函数,一定要自行实现,否则有内存泄漏 ~ArrayList(); //子当中须覆盖并实现父中的纯虚函数 void insert(int pos,int value); void remove(int pos); int at(int pos)const; void modify(int pos,int newValue); //对于父中已实现的虚函数,可以选择覆盖或者不覆盖 //void disp(ostream&os)const;//这个函数可以直接使用父中的实现 private: void setCapacity(int newCapa); }; #endif // _ARRAYLIST_H_ LinkedList.h内容如下: #ifndef _LINKEDLIST_H_ #define _LINKEDLIST_H_ #include "List.h" class LinkedList : public List{ public: //这是单链表节点的结构体 struct Node{ int data; Node *next; Node(int a=0,Node *b=nullptr):data(a),next(b){} }; private: Node *head;//链表的头结点 public: //默认构造函数,构造一个逻辑为空的链表 LinkedList(); //拷贝构造函数,构造一个逻辑上与数内容相同的链表 LinkedList(const LinkedList&rhs); //原生数组构造函数,构造一个内容与给定数组相同的链表 LinkedList(int const a[],int n); //填充构造函数,构造一个内容为n个value的链表 LinkedList(int n,int value); //析构函数,一定要自行实现,否则有内存泄漏 ~LinkedList(); //子当中须覆盖并实现父中的纯虚函数 void insert(int pos,int value); void remove(int pos); int at(int pos)const; void modify(int pos,int newValue); //对于父中已实现的虚函数,可以选择覆盖或者不覆盖 //对于LinkedList,必须重新实现disp函数 void disp(ostream&os)const; private: Node* advance(int pos)const; }; #endif // _LINKEDLIST_H_ main.cpp内容如下: #include "List.h" #include "ArrayList.h" #include "LinkedList.h" using namespace std; int A[1000]; int main(){ List *p = new ArrayList; int n; cin>>n; for(int i=0;i<n;++i){ cin>>A[i]; p->insert(p->getSize(),A[i]); } cout<<*p<<endl; for(int i=0;i<3&&p->getSize()!=0;++i){ p->remove(0); } cout<<*p<<endl; for(int i=0;i<p->getSize();i+=2){ p->modify(i,p->at(i)*10); } cout<<*p<<endl; delete p; p = new LinkedList; for(int i=0;i<n;++i){ p->insert(p->getSize(),A[i]); } cout<<*p<<endl; for(int i=0;i<3&&p->getSize()!=0;++i){ p->remove(0); } cout<<*p<<endl; for(int i=0;i<p->getSize();i+=2){ p->modify(i,p->at(i)*10); } cout<<*p<<endl; delete p; return 0; }
06-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值