1.1.基本

1.&和&&区别

&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。

&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,例如,对于if(str != null && !str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。If(x==33 & ++y>0) y会增长,If(x==33 && ++y>0)不会增长

&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01。

使用0xff来与一个byte进行&运算,其本质原因就是想保持二进制补码的一致性,&0xff可以将高的24位置为0,低8位保持原样(0xFF转化成8位二进制就是11111111)(6.6.6)

扩展:在hashmap散列表里 int hashvalue = (key.hashCode() & 0x7FFFFFFF) % table.length;put的时候通过hashvalue 去寻找key所存储的数组角标。

 

2. short i=i+1和short j+=1,哪个可以运行成功

 

3.String.format("%03d",29)-->29->029 组报文是可以用到。

 

4.编写多线程程序是为了实现多任务的并发执行,从而能够更好地与用户交互。一般有三种方法,Thread,Runnable,Callable.

  Runnable和Callable的区别是,

  (1)Callable规定的方法是call(),Runnable规定的方法是run()。

  (2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得

  (3)call方法可以抛出异常,run方法不可以

  (4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。

 

5.下面哪个不是java语言中的关键字?( B)

A.long B.sizeof C.instanceof D.const

const是Java的一个保留关键字,没有使用。sizeof真的是C/C++的,Java里没有~~

 

6.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?

这个是可以的,一个“.java”源文件里面可以包含多个类,但是只允许有一个public类,并且类名必须和文件名一致。

每个编译单元只能有一个public 类。这么做的意思是,每个编译单元只能有一个公开的接口,而这个接口就由其public 类来表示。

你可以根据需要,往这个文件里面添加任意多个提供辅助功能的package 权限的类。但是如果这个编译单元里面有两个或两个以上的public 类的话,程序就不知道从哪里导入了,编译器就会报错。  

 

7.JAVA修饰符

 java的四个关键字:public、protected、default、private(他们决定了紧跟其后被定义的东西可以被谁使用)

适用范围<访问权限范围越小,安全性越高>

访问权限   类   包  子类  其他包

public     ∨   ∨    ∨     ∨        (对任何人都是可用的)

    protect    ∨   ∨   ∨     ×   (继承的类可以访问以及和private一样的权限)

    default    ∨   ∨    ×     ×   (包访问权限,即在整个包内均可被访问)

    private    ∨    ×    ×     ×   (除类型创建者和类型的内部方法之外的任何人都不能访问的元素)

如果两个或两个以上的(不同的)字段修饰符出现在字段声明,它们出现的顺序需与FieldModifier一致,这只是习惯,但不是必需的。

public protected private static final transient volatile

 

8.static

8.1.修饰变量:

类的所有对象共同拥有的一个属性,也称为类变量。这类似于C语言中的全局变量。类变量在类加载的时候初始化,而且只被初始化一次。在程序中任何对象对静态变量做修改,其他对象看到的是修改后的值。因此类变量可以用作计数器。另外,Java Static变量可以用类名直接访问,不必需要对象。

8.2.修饰方法:

类的所有对象共同拥有的一个功能,称为静态方法。静态方法也可以用类名直接访问,而不必需要对象。所以在静态方法里不能直接访问非静态变量和非静态方法,在Static方法里不能出现this或者super等关键字。(父类的静态方法和子类重写的静态方法是两个没有关系的方法,具体调用哪一个方法是看是哪个对象的引用;这种父子类方法也不在存在多态的性质。《Java编程思想》中这样提到“只有普通的方法调用可以是多态的”。)

8.3.修饰Java代码块:

用static去修饰类里面的一个独立的代码块,称为静态代码块。静态代码块在类第一次被加载的时候执行,而且只执行一次。静态代码块没有名字,因此不能显式调用,而只有在类加载的时候由虚拟机来调用。它主要用来完成一些初始化操作。

8.4.static修饰内部类,普通类是不允许声明为静态的,只有内部类才可以。被static修饰的内部类可以直接作为一个普通类来使用,而不需实例一个外部类。

// 创建静态内部类的实例 OuterClass.NestedStaticClass printer = new OuterClass.NestedStaticClass();

// 创建非静态内部类实例 OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();

(1)内部静态类不需要有指向外部类的引用。但非静态内部类需要持有对外部类的引用。

(2)非静态内部类能够访问外部类的静态和非静态成员。静态类不能访问外部类的非静态成员。他只能访问外部类的静态成员。

(3)一个非静态内部类不能脱离外部类实体被创建,一个非静态内部类可以访问外部类的数据和方法,因为他就在外部类里面。

 

9.java中的==、equals()、hashCode()

1. ==是比较两个对象在JVM中的地址。new产生的对象在堆中,是堆中变量的引用,而是string s1=“1”是指向字符串字面值"nihao"的引用。

2.equals是根类Obeject中的方法。源代码如下:

public boolean equals(Object obj) { return (this == obj);}

可见默认的equals方法,直接调用==,比较对象地址。string重写了:

(1)String类中的equals首先比较地址,如果是同一个对象的引用,可知对象相等,返回true。

(2)若果不是同一个对象,equals方法挨个比较两个字符串对象内的字符,只有完全相等才返回true,否则返回false。

Object 的equals方法比较的是地址。

3.hashcode() Obeject中的方法。

默认情况下,Object中的hashCode() 返回对象的32位jvm内存地址。也就是说如果对象不重写该方法,则返回相应对象的32为JVM内存地址。

 

10. Object的clone()对象克隆

protected Object clone() throws CloneNotSupportedException {  

    if (!(this instanceof Cloneable)) {   throw new CloneNotSupportedException("Class doesn't implement Cloneable");   }  

    return internalClone((Cloneable) this);  

}  

private native Object internalClone(Cloneable o); 

clone方法首先会判对象是否实现了Cloneable接口,若无则抛出CloneNotSupportedException, 最后会调用internalClone. intervalClone是一个native方法,一般来说native方法的执行效率高于非native方法。

当某个类要复写clone方法时,要继承Cloneable接口。

10.2.浅克隆(shadow clone)

   克隆就是复制一个对象的复本.若只需要复制对象的字段值(对于基本数据类型,如:int,long,float等,则复制值;对于复合数据类型仅复制该字段值,如数组变量则复制地址,对于对象变量则复制对象的reference。

基本类型可以使用浅克隆,而对于引用类型,由于引用的是内容相同,所以改变c2实例对象中的属性就会影响到c1。

10.3.深克隆(deep clone)

    深克隆与浅克隆的区别在于对复合数据类型的复制。若对象中的某个字段为复合类型,在克隆对象的时候,需要为该字段重新创建一个对象。

10.4、总结:

10.4.1.克隆方法用于创建对象的拷贝,为了使用clone方法,类必须实现java.lang.Cloneable接口重写protected方法clone,如果没有实现Clonebale接口会抛出CloneNotSupportedException.

10.4.2.在克隆java对象的时候不会调用构造器

10.4.3.java提供一种叫浅拷贝(shallow copy)的默认方式实现clone,创建好对象的副本后然后通过赋值拷贝内容,意味着如果你的类包含引用类型,那么原始对象和克隆都将指向相同的引用内容,这是很危险的,因为发生在可变的字段上任何改变将反应到他们所引用的共同内容上。为了避免这种情况,需要对引用的内容进行深度克隆。

 

11.String、StringBuffer与StringBuilder之间区别

这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。

11.1.首先说运行速度,或者说是执行速度,

在这方面运行速度快慢为:StringBuilder > StringBuffer > String

  String最慢的原因: String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。

1 String str="abc"; 2 System.out.println(str); 3 str=str+"de"; 4 System.out.println(str);

  如果运行这段代码会发现先输出“abc”,然后又输出“abcde”,好像是str这个对象被更改了,其实,这只是一种假象罢了,JVM对于这几行代码是这样处理的,首先创建一个String对象str,并把“abc”赋值给str,然后在第三行中,其实JVM又创建了一个新的对象也名为str,然后再把原来的str的值和“de”加起来再赋值给新的str,而原来的str就会被JVM的垃圾回收机制(GC)给回收掉了,所以,str实际上并没有被更改,也就是前面说的String对象一旦创建之后就不可更改了。所以,Java中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以慢。

  而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。

  另外,有时候我们会这样对字符串进行赋值

1 String str="abc"+"de"; 2 StringBuilder stringBuilder=new StringBuilder().append("abc").append("de"); 3 System.out.println(str); 4 System.out.println(stringBuilder.toString());

  这样输出结果也是“abcde”和“abcde”,但是String的速度却比StringBuilder的反应速度要快很多,这是因为第1行中的操作和 String str="abcde"; 是完全一样的,所以会很快,而如写成下面这种形式

1 String str1="abc"; 2 String str2="de"; 3 String str=str1+str2;

  那么JVM就会像上面说的那样,不断的创建、回收对象来进行这个操作了。速度就会很慢。

11.2. 再来说线程安全

  在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的

  如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。

  3. 总结一下

  String:适用于少量的字符串操作的情况

  StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

  StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

 

12.内部类模拟实现多继承

/**  *  橡皮类  * */

public abstract class Eraser {  public abstract void erase(); }

/**  *  铅笔类 * */

public abstract class Pencil { public abstract void wirte(); }

/**  *  做一个既有铅笔功能又有橡皮擦功能类

 *  (用接口完全可以实现,这里只是假设这种情况,模拟多继承) * */

public class PencilWithEraser{

  private MyPencil pencil = new MyPencil();

  private MyEraser eraser = new MyEraser();

 /** * 继承了铅笔的功能 * */ 

 private class MyPencil extends Pencil{  public void wirte() { System.out.println("use to wirte"); } ß }

/*写一个既有笔功能又有橡皮侧功能的类 **/

 private class MyEraser extends Eraser {  public void erase() { System.out.println("use to erase");  } ß }

 /** 本类自己的方法* */

  public void wirte(){   pencil.wirte();  }

  public void eraser(){ eraser.erase();  }

}

public class Test { //测试类

  public static void main(String[] args) {

PencilWithEraser pencilWithEraser = new PencilWithEraser();

         pencilWithEraser.wirte();

       pencilWithEraser.eraser();

  }

}

这个类既有笔又有橡皮擦功能了。模拟实现了Java多继承。

 

13.将字符串转换成数字(考虑小数、负数)

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值