java一些笔记

Java中静态变量只能在类主体中定义,不能在方法中定义。 静态变量属于类所有而不属于方法。
多态==晚绑定或动态绑定
不要把函数重载理解为多态,因为多态是一种运行期行为,不是编译器行为。
多态:父类的引用指向子类的实例。
比如 Parent p = new Child()
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;
如果有,再去调用子类的同名方法。
静态方法特殊,静态方法只能继承,不能覆盖,如果子类有和父类相同的静态方法,只是起到隐藏父类方法的作用。这时候,谁的引用就调用谁的方法。

//一道多态题<阿里巴巴>
下面代码的输出是什么?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Base
{
     private String baseName =  "base" ;
     public Base()
     {
         callName();
     }
 
     public void callName()
     {
         System. out. println(baseName);
     }
 
     static class Sub  extends Base
     {
         private String baseName =  "sub" ;
         public void callName()
         {
             System. out. println (baseName) ;
         }
     }
     public static void main(String[] args)
     {
         Base b =  new Sub();
     }
}

正确答案: A   你的答案: B (错误)

null
sub
base

1.首先,需要明白 类的加载顺序
(1) 父类静态代码块(包括静态初始化块,静态属性,但不包括静态方法)
(2) 子类静态代码块(包括静态初始化块,静态属性,但不包括静态方法 )
(3) 父类非静态代码块( 包括非静态初始化块,非静态属性 )
(4) 父类构造函数
(5) 子类非静态代码块 ( 包括非静态初始化块,非静态属性 )
(6) 子类构造函数
其中:类中静态块按照声明顺序执行,并且(1)和(2)不需要调用new类实例的时候就执行了(意思就是在类加载到方法区的时候执行的)
2.其次,需要理解子类覆盖父类方法的问题,也就是 方法重写实现多态问题。
Base b = new Sub(); 它为多态的一种表现形式,声明是Base,实现是Sub类,  理解为  b  编译时表现为Base类特性,运行时表现为Sub类特性。
当子类覆盖了父类的方法后,意思是父类的方法已经被重写, 题中  父类初始化调用的方法为子类实现的方法,子类实现的方法中调用的baseName为子类中的私有属性。
由1.可知,此时只执行到步骤4.,子类非静态代码块和初始化步骤还没有到,子类中的baseName还没有被初始化。所以此时 baseName为空。 所以为null。

类变量在不设置初始值时,会进行默认值赋值,而局部方法中声明的变量则必须进行初始化,他不会进行默认值赋值。final变量定义的时候,可以先声明,而不给初值,这种变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化


所谓构造方法, 1,使用关键字new实例化一个新对象的时候默认调用的方法; 2,构造方法所完成的主要工作是对新创建对象的数据成员赋初值。 使用构造方法时需注意以下几点 1.构造方法名称和其所属的类名必须保持一致; 2.构造方法没有返回值,也不可以使用void; 3.构造方法也可以像普通方法一样被重载; 4.构造方法不能被static和final修饰; 5.构造方法不能被继承,子类使用父类的构造方法需要使用super关键字

如果在循环的过程中调用集合的remove()方法,就会导致循环出错,例如:
for(int i=0;i<list.size();i++){
    list.remove(...);
}
循环过程中list.size()的大小变化了,就导致了错误。

所以,如果你想在循环语句中删除集合中的某个元素,就要用迭代器iterator的remove()方法,因为它的remove()方法不仅会删除元素,还会维护一个标志,用来记录目前是不是可删除状态,例如,你不能连续两次调用它的remove()方法,调用之前至少有一次next()方法的调用。


下列哪个选项是Java调试器?如果编译器返回程序代码的错误,可以用它对程序进行调试。

正确答案: C   你的答案: B

java.exe
javadoc.exe
jdb.exe
javaprof.exe
java,exe是java虚拟机
javadoc.exe用来制作java文档
jdb.exe是java的调试器
javaprof,exe是剖析工具

关于ThreadLocal  以下说法正确的是

正确答案: D E   你的答案: A D E

ThreadLocal继承自Thread
ThreadLocal实现了Runnable接口
ThreadLocal重要作用在于多线程间的数据共享
ThreadLocal是采用哈希表的方式来为每个线程都提供一个变量的副本
ThreadLocal保证各个线程间数据安全,每个线程的数据不会被另外线程访问和破坏

1、ThreadLocal的类声明:
public class ThreadLocal<T>
可以看出ThreadLocal并没有继承自Thread,也没有实现Runnable接口。所以AB都不对。
2、ThreadLocal类为每一个线程都维护了自己独有的变量拷贝。每个线程都拥有了自己独立的一个变量。
所以ThreadLocal重要作用并不在于多线程间的数据共享,而是数据的独立,C选项错。
由于每个线程在访问该变量时,读取和修改的,都是自己独有的那一份变量拷贝,不会被其他线程访问,
变量被彻底封闭在每个访问的线程中。所以E对。
3、ThreadLocal中定义了一个哈希表用于为每个线程都提供一个变量的副本:
 static class ThreadLocalMap {

        static class Entry extends WeakReference<ThreadLocal> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal k, Object v) {
                super(k);
                value = v;
            }
        }

        /**
         * The table, resized as necessary.
         * table.length MUST always be a power of two.
         */
        private Entry[] table;
}
所以D对。

Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。

两个最基本的java回收算法:复制算法和标记清理算法
复制算法:两个区域A和B,初始对象在A,继续存活的对象被转移到B。此为新生代最常用的算法
标记清理:一块区域,标记可达对象(可达性分析),然后回收不可达对象,会出现碎片,那么引出
标记-整理算法:多了碎片整理,整理出更大的内存放更大的对象
两个概念:新生代和年老代
新生代:初始对象,生命周期短的
永久代:长时间存在的对象
整个java的垃圾回收是新生代和年老代的协作,这种叫做分代回收。
P.S: Serial New收集器是针对新生代的收集器,采用的是复制算法
Parallel New(并行)收集器,新生代采用复制算法,老年代采用标记整理
Parallel  Scavenge(并行)收集器,针对新生代,采用复制收集算法
Serial Old(串行)收集器,新生代采用复制,老年代采用标记整理
Parallel  Old(并行)收集器,针对老年代,标记整理
CMS收集器,基于标记清理
G1收集器:整体上是基于标记  整理  ,局部采用复制

对文件名为Test.java的java代码描述正确的是()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Person {
     String name =  "No name" ;
     public Person(String nm) {
         name = nm;
     }
}
class Employee extends Person {
     String empID =  "0000" ;
     public Employee(String id) {
         empID = id;
     }
}
public class Test {
     public static void main(String args[]) {
         Employee e =  new Employee( "123" );
         System.out.println(e.empID);
     }
}

正确答案: C   你的答案: B

输出:0000
输出:123
编译报错
输出:No name

子类的构造方法总是先调用父类的构造方法,如果子类的构造方法没有明显地指明使用父类的哪个构造方法,子类就调用父类不带参数的构造方法。
而父类没有无参的构造函数,所以子类需要在自己的构造函数中显示的调用父类的构造函数。

方法重写应遵循“三同一小一大”原则:
  1. “三同”:即方法名相同,形参列表相同,返回值类型相同;
  2. “一小”:子类方法声明抛出的异常比父类方法声明抛出的异常更小或者相等;
  3. “一大”:子类方法的访问修饰符应比父类方法更大或相等。

关于下面程序 ThisTest .java 运行结果 说法正确的是 : ( )

1
2
3
4
5
6
7
8
public class ThisTest {
             public static void main(String args[]) {
                 String x= "7" ;       
         int y = 2;
                 int z=2;              
         System.out.println(x+y+z);
             }  
}


正确答案: B   你的答案: D (错误)

11
722
22
程序有编译错误

+号两边如果有一边为字符类型  则为字符串连接
如果变为y+z+x 则等价于(y+z)+x  输出47

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值