博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java学习
阅读量:6613 次
发布时间:2019-06-24

本文共 4841 字,大约阅读时间需要 16 分钟。

hot3.png

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的线程恢复执行。

转载于:https://my.oschina.net/yizhangxyz/blog/790186

你可能感兴趣的文章
SVG图形之几何图形——学习笔记2
查看>>
第九章 构造数据类型实验
查看>>
Linux(Ubuntu)下安装NodeJs
查看>>
种子填充算法描述及C++代码实现
查看>>
JavaScript之Var关键字
查看>>
jmeter 启用gzip压缩——解决测试中web服务器上行流量过大的问题
查看>>
Linux - Tips
查看>>
Python - Fabric简介
查看>>
ios根据gps坐标来计算两点间的距离
查看>>
ICCV 2013 is coming!!!
查看>>
转 gSOAP中使用TCP协议传输数据
查看>>
C#的扩展方法学习
查看>>
测试数据库连接是否正常 Sql server 2005
查看>>
[转载].NET商业软件源码保护
查看>>
文字播放
查看>>
ddchuxing——php面试题及答案
查看>>
Kali渗透测试——快速查找Metasploit的模块
查看>>
团队项目(一)(江山代有才人秃队)
查看>>
Java中几种常见的消息对话框
查看>>
Cesium学习笔记(九):导入3D模型(obj转gltf)
查看>>