文档章节

java学习

y
 yizhangxyz
发布于 2016/11/18 10:52
字数 2277
阅读 7
收藏 0

1 java数据类型可以自动向上转,但是不能向下转。
比如int a =1;  short s = a;//报错

2 小数默认是double双精度的。单精度要加上f。
比如0.3是double型的,0.3f才是float型的。

3 字符串问题。java和c++一样有个常量池。字符串常量就存放在那里。
String s = "abc"; s指向常量池的 “abc”
String s1 = new String("abc");用常量池的"abc"初始化堆里面的s1。
String的intern()方法返回他在常量池里面的引用(指针?),如果没有,那么先在常量池创建再返回。
常量池里面的数据是无法修改的。String的replace方法会返回一个新的字符串。

4 hashtable和hashmap。
hashtable是线程安全的(有synchronized修饰)
hashmap不是线程安全的,但是可以存放一个为null的键值和value。

5 参数传值还是引用。java都是按值传递。当传递基础类型的时候传递数据的副本。当传递对象的时候,传递对象引用的副本(指针的值?)。

6 java内存回收。jvm会自动清除没有被指向的对象(c++里面的引用计数?)。那么对象的指向是什么意思呢(即引用计数是如何工作的?)。
void fun(){
A a = new A();
}a在fun调用结束后被释放,所以 a指向的内存使用计数减1。
A a = new A();
a = null;赋值为null,引用计数减1。
a = b;   赋其他值,引用计数减1。
通过调用System.gc()可以强制执行一次垃圾回收。(System.gc()其实是对Runtime.getRuntime().gc()的简单包装)

7 static class

只有内部类可以声明为static class
static 内部类和非static 内部类有以下区别:
a static内部类只能访问外部类的static方法或者成员。非static内部类可以访问非static方法和成员(当然也可以访问static成员和方法)
b static内部类可以声明shatic方法和成员,非static内部类不能声明static方法或者成员
c static内部类可以单独初始化。Inner i = new Outer.Inner();
非static内部类Outer o = new Outer();Inner i = o.new Inner();

8 内部类可以访问外部类的private方法或者变量

9 final成员变量必须在声明时初始化。如果是static final,可以在static块里面初始化。

10 Base base = new Derived(); Derived是Base的派生类
base instanceof Base 为true
base instanceof Derived为true

11 重写equals要遵守的规范(如果不准照这个规范,集合类在操作时会出问题):
自反性:x.equals(x)肯定为true
对称性:x.equals(y) 为true,那么y.equals(x)肯定为true
传递性:x.equals(y) 为true,y.equals(z)为true,那么x.equals(z)肯定为true
一致性:x.equals(y) 为true,在x,y未改变的时候多次比较依然为true

12 Object的getClass()方法返回真实的classname
Base base1 = new Derived();
base.getClass()返回Derived。

13 java的hashcode用于散列函数。该函数与equal紧密相关,在覆盖了equal的时候必须覆盖hashcode方法。并且要准照以下规范
a 在程序运行期间,只要equal方法用到的信息没有被修改,那么hascode返回的数值必须一致。多次运行程序则不必相等。
b 两个对象equal为true,那么hashcode值也必须相等。
c  两个对象equal为false,那么hashcode值可以相同也可以不相同,但是不同的话可以提高散列表的性能。

14通过java反射只能调用对象的public方法,否则会报错:java.lang.NoSuchMethodException。static域也是同样的,查阅资料说setAccessible方法可以修改反问权限,试了没有效果。

15 对象clone。Object的clone方法是protected的本地方法,他可以对对象进行逐域拷贝。要使用clone方法,必须重载clone方法,并将其设置为public的。然后调用super.clone(),但是这时候会抛异常,因为类必须要实现Cloneable接口才具备Object的clone功能。当然我们也可以不使用Object的clone方法,转而自己new一个对象,然后逐域赋值。注意,object的clone只是一个浅拷贝。如果类成员变量是基础类型是没有问题的,但如果存在对象变量,那么这个时候默认的clone其实只是拷贝的对象的引用(指针?),变量对象是共享的。如果要实现深拷贝,只有堆变量进行依次clone。

16 访问权限控制
protected除了子类可见,并且包内可见。这和c++不一样,c++的protected只有子类可见。 
子类继承的时候,不允许缩小基类方法的访问权限,避免无法正常使用基类方法。(java编译就会报错)
接口方法必须全是public的

17 java的List(线性表)共有3种实现
ArrayList和c++的Vector一样,也是可变长度数组。在添加元素的时候可能导致数组元素的移动
Vector,和ArrayList差不多,但是增加线程同步,所以效率会比ArrayLIst低
LinkedList,链表实现。

18 StringBuffer是线程安全的(基本废弃),StringBuilder不是线程安全的。

19 java同c++一样,不要在构造函数里面调用虚方法(java里被子类覆盖的方法)。java里面的clone方法实现和构造器实现很相似,所以不能在clone方法里面调用虚方法。

20 基类数组可以指向子类数组,但是泛型不可以
Object[] objs = new Integer[10]; //ok
ArrayList<Object> list = new ArrayList<Integer>();//错误

21 java泛型(c++模板)同函数重载(overload)一样都是编译期行为。覆盖(c++虚函数)都是运行期行为

22 c++中的对象可以在栈上创建,但是java不行,只能通过new 在堆上创建
public class Base{
    public Integer INT_VALUE = 0;  
    public Base(){
        show();
    }
    public Base(int v){
        INT_VALUE = v;
    } 
    public void show(){
        System.out.println("base show------>"+INT_VALUE);
    }
}

在java中 Base b;是不会调用构造函数的,而在c++中是可以的。

23. i++和 ++i都不具有原子性。

24.volatile变量修饰符符使线程在获取变量值的时候每次都从内存去取,而不是寄存器中(线程栈?)获取。保证变量修改的及时性。
示例
public class MyThread extends Thread{
    private volatile boolean pleaseStop = false;  
    @Override
    public void run(){
        while (!pleaseStop) {  //如果不加volatile,那么每次都是取的线程内部的副本(每个线程都有单独的线程栈,或者说cpu和内存间的高速缓存?)
        }  
        System.out.println("thread end---------------->");
    }
    public void tellMeToStop() {  
        pleaseStop = true;  
    }  
}
MyThread thread = new MyThread();
thread.start();
try {
    Thread.sleep(1);
} catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
thread.tellMeToStop();//如果不加volatile。那么这句话无法停掉线程

25.java同步的方法。
a.synchronized关键字,修饰方法或者语句块。
b.使用Lock(ReentrantLock),和synchronized有相同的效果,但必须放在try catch中,避免异常的时候无法释放锁。和synchronized区别有以下3点:
    b1:等待可中断,线程长期持有锁的时候,等待的线程可以选择放弃,避免死锁
    b2:可以创建公平锁(按照申请顺序获得锁,默认是非公平锁,当然公平锁会消耗性能)
    b3:可以绑定多个对象

26.java引用类型。
⑴强引用(StrongReference):Object obj = new Object();没有引用的时候才会删除。否则不会删除改对象
⑵软引用(SoftReference):空间不足的时候就会回收。否则不会回收。SoftReference<A> softReference = new SoftReference<A>(new A());
⑶弱引用(WeakReference):等于没有引用。垃圾回收的时候直接回收。但是垃圾回收有个周期,所以会短暂持有一段时间
⑷虚引用(PhantomReference):等于没有引用。和弱引用的区别在于,他必须和引用队列ReferenceQueue联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。
ReferenceQueue queue = new ReferenceQueue ();
PhantomReference pr = new PhantomReference (object, queue); 

27.Serializable序列化。
a.serialVersionUID表示序列化的版本,只有版本相同才可以进行反序列化。
b.反序列化的时候并不会调用构造器。
c.可以用父类对象反序列化派生类对象。
d.非静态内部类不应实现Serializable。因为他对如何保存外部类没有明确规定。

28.ThreadLocal是为每一个线程分配一个变量副本。各个线程之间互不干涉。

29.sleep(),wait(),notify(),yield() 区别:
sleep:指定当前线程休眠一定时间。不释放对象锁,就是说如果有synchronized同步块,其他线程不能访问共享数据
yield:和sleep差不多,但是不能指定休眠时间,并且只能让同优先级的线程有执行的机会
wait:让线程休眠指定时间,与sleep不同之处在于该方法必须在synchronized同步块内使用,他会释放对象锁。
notify:让wait的线程恢复执行。

© 著作权归作者所有

共有 人打赏支持
y
粉丝 1
博文 67
码字总数 42366
作品 0
成都

暂无文章

GO 数组相关操作

package mainimport("fmt""math/rand""time")func main() {//数组的几种定义方式var arr1 [3]int = [3]int{1,2,3}var arr2 = [3]int{4,5,6}arr3 := [3]string{"h", "w", ......

汤汤圆圆
43分钟前
1
0
JAVA 中interrupt、interrupted和isInterrupted的区别

首先,我们说明下三个方法的功能 interrupt() 向当前调用者线程发出中断信号 isinterrupted() 查看当前中断信号是true还是false interrupted() 是静态方法,查看返回当前中断信号并将中断信号...

我爱春天的毛毛雨
47分钟前
1
0
Coding and Paper Letter(二十二)

资源整理。 1 Coding: 1.开源项目openeo api。oponEO开发了一个开放的API,以简单统一的方式将R,python和javascript客户端连接到对地观测大数据云平台的后台。 此存储库包含此API,即oponE...

胖胖雕
今天
1
0
RxJS的另外四种实现方式(三)——性能最高的库

接上篇 RxJS的另外四种实现方式(二)——代码最小的库(续) 代码最小的库rx4rx-lite虽然在性能测试中超过了callbag,但和most库较量的时候却落败了,于是我下载了most库,要解开most库性能...

一个灰
今天
6
0
马太效应

马太效应

yizhichao
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部