java基础知识汇总

0. jdk中的bin目录常用的命令:javadoc, javap, java,javac,jar,javah,jstack,native2ascii,jmap等

   ${JAVA_HOME}/bin/jmap -dump:live,format=b,file=/home/mytest/heap.hprof <pid>

     

    遇到OOM(Out of Memory)的问题,为了分析内存和JVM的垃圾回收器GC问题,一并把JVM相关的一些工具也研究了一下
  1. jps:Java进程查看工具,实际上它和Unix/Linux上面的ps命令的功能差不多
  2. jstat:Java内存使用情况监控工具
  3. jmap:输出JVM内存中对象的工具

1.jdk中的jre和jre的区别,三个lib文件夹的区别:

     jdk中的jre是开发jre,另一个是通用jre(两个jre大体相同(1.6之前会有jdk下的jre比通用jre多一个server文件夹)。jdk中使用java编写的工具只能使用开发jre运行。

    一般用户执行java程序时,使用的是通用jre,此时开发jre同样可用,只是通用jre即可实现常用功能。通常普通java程序使用通用jre,开发环境使用开发jre,实现分工。

    三个lib:jdk下的lib是给java开发环境的jar包,供jdk使用,如java编写的工具等,开发jre下的lib是运行时需要的jar包,如常见的外部驱动包(因为编译时使用开发jre,不适用通用jre),通用jre中的lib只是运行java程序时需要的jar包,是JVM需要使用的,包括标准类库和扩展类。


    eclipse中不需要制定ClassPath,eclipse自己能自动找到。如果eclipse中指定了jdk路径,则jre则默认是开发jre。

    


2.classPath:

   系统中默认是没有的,需要自己手动创建。配置:.;+需要配置的path(其中.代表当前路径,配置的目的是使相对于当前的java源文件访问相关的路径或者文件)。dt.jar,tools.jar通常配置到classpath中。

   JVM在第一次使用一个类时,会到classpath所指定的路径里去找这个类所对应的字节码文件并读进JVM保存起来,这个过程称之为类加载。

参考文章:http://blog.csdn.net/openxmpp/article/details/8564598

 a. 一个jvm中默认的classloader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职:Bootstrap ClassLoader负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等。Extension ClassLoader 负责加载java扩展类,主要是%JRE_HOME/lib/ext 目录下的jar和class。App ClassLoader 负责加载当前java应用的classpath中的所有类。

 b. Bootstrap ClassLoader是JVM级别的,由C++撰写;Extension ClassLoader、App ClassLoader都是java类,都继承自URLClassLoader超类。Bootstrap ClassLoader由JVM启动,然后初始化sun.misc.Launcher ,sun.misc.Launcher初始化Extension ClassLoader、App ClassLoader。

c. 基本上,每一个ClassLoader实现,都有一个Parent ClassLoader。可以通过ClassLoader的getParent方法得到当前ClassLoader的parent。Bootstrap ClassLoader比较特殊,因为它不是java class所以Extension ClassLoader的getParent方法返回的是NULL。


3.八大基本变量:基本变量都是在栈上分配的,每种基本类型都在静态存储区有相对应的常量池与之对应,常量池中的数据在运行时随基本类型的创建而存储存储。

    boolean:1位,但仍然占有1个字节

    byte:1个字节,8位

    char :2个字节,16位

    short:2个字节,16位

    int:占用4个字节,32位,最高位是符号位。取值范围:2^31-----2^31 -1

    float:4个字节,32位,有效小数是8位。

    double:8个字节,64位,有效小数是16位。

    long:8个字节,64位

   

   PS:声明属性不开辟栈内存空间,只有在初始化时才会开辟相对应的内存空间;通常属性第一次初始化会在栈上分配,但是涉及到两次或者多次连续分配时第二次及以后的分配在堆内存上;

 


4.基本操作运算符和基本类型相互之间的转换:

  基本运算符有:算术运算符(++,%),关系运算符(==),按位运算符(&,|,^,~,>,>>,>>>),逻辑运算符(&&,||,!),其他如三元运算符等。

  类型之间转换:在类型匹配时,小类型可以自动转换为大类型(int--->double),大类型可以强制转化为小类型(double-->int),如boolean不能和任何其他类型转换

 PS:

(1)“==”是浅层比较,直接比较其所指向的直接地址(如常量池中地址),如a=5,b=5;a==b指比较栈上变量a指向常量池中存放5的地址和栈上变量b指向常量池中存放5的地址,两者在常量池中必然是同一个。

equals通常是两层比较,栈内存中引用指向堆内存对象,对象的属性指向常量池中的地址。所以对象通常使用equals的原因也在与此。==比较的只是栈内存指向对内存的地址

(2)按位与(&),按位或(|) 不遵循我们的思维,没有短路的存在判断,其每个条件都会判断,效率有点低下,如:(if(3>4|c++>3))由于所有条件都会执行,故而可以改变c的值(2)逻辑与(&&)和逻辑或(||)遵循我们的思维,有短路存在


5.  



6.数组:

 a.数组中易抛空指针异常(NullPoint)和数组下标越界异常;
 b..数组定义没有开辟空间,但极大可能抛空指针异常;声明并开辟空间后也可能会抛空指针异常;对象数组会在堆空间内开两次空间,第二次指向的是对象;基本类型是在堆空间内开一次空间,存放的值为常量池中的引用。
 c..数组的复制:
  1.简单的“=”并没有完成复制,只是两个数组引用指向同一个对象;            2.十二种排序算法中,常用的为快排和归并;也可以用Util包下的Arrays类
  3.对于数组的复制可以用循环赋值完成,也可以用System.ArrayCopy();
 

d..二维数组:本质上是在一维数组下再开一维,即在内存中只存在一维数组,并且每个一维数组都是连续的;

e.数组的名称就是数组的首地址,同样方法的名称也是方法的首地址,只是前者一般在堆内存(2开头地址)中,后者一般在代码段(4开头地址)中


7.类和对象

  a.在类中,属性按队列存放,方法按堆栈存放,并且方法为所有对象共享,但调用属性由this指针决定;

  b.类中有块,属性和方法,因此静态优于动态加载,属性优于方法加载,块优于一般方法,一般方法优于构造方法;静态属性和方法随类加载而加载。

  c.方法中如果可以,最好直接调用属性,不建议调用方法,这样可以提高效率,节省空间;同样由于静态成员是整个类所共享的,因此对于变量来说最好遵循哪用哪定的原则,这样可以提高效率

 d.修饰外部类只能用public和缺省,修饰内部类可以用四种,修饰属性和方法也可以用四种,本质上,内部类就是类的一个属性,可以调用,但是不能
  在main方法中直接调用,main是静态的方法,期内所有内容要么是静态的,要么就是引用调用;

 e.类中的块分为四种:静态块(static{},最先执行,仅执行一次),构造块({},优先于构造方法执行,每次创建对象都调用),普通代码块(直接定义在方法中的代码),同步代码块(synchronized关键字声明的代码)。

  f.当子类覆盖父类中的方法时,子类覆盖父类的方法的访问权限不能比父类更严谨。

    当子类覆盖父类中的方法时,子类不能抛出比父类更大的异常。




8.抽象类,内部类和接口

   接口:接口中的所有属性都是public static final类型的常量,一旦声明,必须赋初始值,并且赋值以后不允许任何改变。

   内部类:内部类可以在类中,也可以在方法中,在类中即将其当做外部类的一个属性,在方法中就将其当做方法中的变量。 Out out;Out.Innner in =out.new Inner();

  匿名内部类:是在接口和抽象类基础上发展起来的。匿名内部类通常都是作为方法的参数传递的。如Runnable的使用,main方法中 new A().function()等使用


9.final:修饰属性,属性是不可更改的,修饰方法,方法是不可覆盖和重写的;修饰类,类是不能被继承的。

   final关键字提高了性能。JVM和Java应用都会缓存final变量。JVM会对方法、变量及类进行优化。final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。    如:String是不可变类的代表。不可变类有很多好处,譬如它们的对象是只读的,可以在多线程环境下安全的共享,不用额外的同步开销等等。


10.

声明为volatile的简单变量如果当前值由该变量以前的值相关,那么volatile关键字不起作用,达不到各个线程共享变量的目的,可以使用javap查看。也就是说如下的表达式都不是原子操作,如n = n + 1; n++;

如果要想使这种情况变成原子操作,需要使用synchronized关键字,使用同步的方式实现。




   


     

   

  

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值