欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA杂记

程序员文章站 2024-03-13 15:29:45
...

x=x+1,x+=1,x++   x++效率最高;x=x+1需4步,x+=1需3步,x++需2步。

 

Java中涉及byte、char和short类型的运算操作首先会把这些值转换为int类型,然后对int进行运算,最后得到int类型结果。

short s=1;s=s+1; 错误     short s=1;s+=1; 正确

public class Test {
	public static void main(String args[]){
		char a;
		a = '*';
		System.out.println(a);
		int ia = (int)a;
		System.out.println(ia);
		a += a;
		System.out.println(a);
	}
}

*
42
T

  

assert Expression1:Expression2

assert断言默认不开启,需加参数-enableasserttions或-ea。

Expression1不通过则抛java.lang.AssertionError异常打印Expression2

 

error和exception的区别:

error表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。

exception表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

 

反射可以在运行时加载、探知、使用编译期间完全位置的classes。换句话说,java程序可以加载一个运行时才得知名称的class、获悉其完整构造(但不包括methods定义),并生成其对象实例、或对其fields设值,或唤起其methods。

 

final、finally、finalize区别

final修饰的变量初始化有2个地方,一是其定义处,二是在构造函数中,两者只能选其一;

final修饰的方法有两个原因:一是不允许从此类继承的类来覆写这个方法,但是继承仍然可以继承这个方法,也就是说可以直接使用;二是允许编译器将所有对次方法的调用转化为inline(行内)调用的机制,但要注意程序代码迅速膨胀。

 

String的形参传递:

public class test {
	public static void main(String[] args) {
		String str = "hello";
		changeStr(str);
		System.out.println(str);
	}
	public static void changeStr(String str){
		str += "1";
	}
}
//Output:hello

 

字符串是值传递。Sring的本质是一个值,如果把值当作一个仓库的话,函数就是在某块空地(栈的临时存储区)上重建了一个一模一样的仓库。原来的仓库假设为A,后面的仓库假设为B。当changeStr函数中str改变时只是改变仓库B里面的屋子。这有点像基本类型。

 

类内访问私有成员

public class Test {
	private int court;
	Test(int i){ court = i; }
	public static void main(String[] args) {
		Test t = new Test(99);
		System.out.println(t.court);
	}
}
//Output:99

 

定义在类内的变量会被赋予一个默认的值

public class Test {
	static boolean b;
	public static void main(String[] args) {
		System.out.println(b);
	}
}
//Output:false

 

从键盘接收输入数据:

public class Test {
	static String getInput(){
		String str = "";
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		try{
			str = br.readLine();
		} catch(IOException e){ return "IOException"; }
		return str;
	}
	public static void main(String[] args) {
		System.out.println(getInput());
	}
}

 

判断一个整数是不是2的阶次方:

public class Test {
	static void check(int d){
		if( ((d-1)&(d))==0 && (d!=0) ) System.out.println("ok");
		else System.out.println("false");
	}
	public static void main(String[] args) {
		check(64);
	}
}

 

switch的参数是byte、char、short、int、enum。

 

Heap和Stack区别

堆是运行时数据区,类的对象从中分配空间。

栈数据可以共享(int a=3;会先在站中查找有没有3),栈中数据大小与生存期必须是确定的,栈主要存放一些基本类型的变量和引用。

String是一个特殊的包装类数据,String str = new String("abc");新创建一个对象  String str = "abc";会先从常量池查找有没有存放“abc”,有则指向。

String str1 = "abc"; String str2 = "abc"; str1==str2  -----> true

String str1 = new String("abc"); String str2 = new String("abc"); str1==str2  -----> false

 

HashMap和Hashtable

Hashtable是线程安全的。

HashMap没有分类或排序,允许一个null键和多个null值,Hashtable不允许null键和null值。

HashMap将Hashtable的contains()去掉,改成containsvalue(),containskey()

 

内部类或嵌套类在类层级上没有限制,内部类可以是私有类。

 

重载overload:

每个重载方法的参数的类型和(或)数量必须是不同,返回类型并不足以区分所使用的是哪个方法。

Java的自动类型转换也适用于重载方法的自变量,例如只有test(double),test(int i = 88)则会调用到test(double)。只有找不到精确匹配时,Java的自动转换才会起作用。

 

继承的方法修饰词static,final

父类的final、static方法会继承到子类,子类可以调用但不能覆盖;

子类可以重新定义与父类static方法一样的方法(含static关键字),当子类不能重新定义与父类final方法一样的方法(含final关键字)。

 

Only constructors can invoke constructors.子类的构造函数如果要引用super的话,必须把super放在构造函数的首位。this()同理,只能出现在被构造函数调用,且只能出现在第一行。

 

    子类构造函数调用父类构造函数时,注意父类构造函数会调用子类的多态函数,同时注意变量不会有多态、父子类重名变量的可见性:

class Base{   
    int i;   
    Base(){   
        add(1);   
        System.out.println(i);   
    }   
    void add(int v){   
        i += v;   
        System.out.println(i);   
    }   
}   
class MyBase extends Base{   
//  int i = 1;   
    MyBase(){   
        add(2);   
    }   
    void add(int v){   
        i += v*2;   
        System.out.println(i);   
    }   
}   
public class Test {   
    public static void main(String args[]){   
        go(new MyBase());   
    }   
    static void go(Base b){   
        b.add(8);   
    }   
}   
//output:2  2  6  22  
//去掉注释的结果值得注意 output:2  0  5  21

首先执行new MyBase(),调用父类构造函数Base();在Base()中执行add()方法,这里需要注意,这个add方法由于实在新建MyBase对象时调用的,所以会首先查找MyBase类中是否有次方法,所以Base()函数中的add(1)实际上执行的是

void add(int v){
  i += v*2;
  System.out.println(i);
}
同时注意变量i在父类变化会带到子类。

注意到程序中的注释部分,若去掉注释,则在执行上面流程时,在Base()函数调用add(1),i是MyBase中定义的i,此时i还没有被初始化,所以是0。若在MyBase定义了i,则在MyBase类中见到的i是在MyBase类定义的i,同时注意初始化问题

 

数组没有length()这个方法,有length属性,String有length()方法。

 

String与char的比较:

import java.util.Arrays;
public class Test {
	public static void main(String args[]){
		String s = "hello";
		String str = "hello";
		char c[] = {'h', 'e', 'l', 'l', 'o'};
		char ch[] = str.toCharArray(); //String转换成char[]
		
		if(s.equals(ch)) System.out.println("true");
		else System.out.println("false");  //1
		
		if(ch == c) System.out.println("true");
		else System.out.println("false");  //2
		
		if(ch.equals(c)) System.out.println("true");
		else System.out.println("false");  //3

		if(Arrays.equals(ch, c)) System.out.println("true");
		else System.out.println("false");  //4
		
		String s2 = new String(c); //char[]转换成String
		if(s2 == (s)) System.out.println("true");
		else System.out.println("false");  //5
		
		if(s2.equals(s)) System.out.println("true");
		else System.out.println("false");  //6
	}
}

false
false
false
true
false
true

1,char和String是两种不同的类型,所以比较结果不同;

3,在数组上调用equals,就是Object里面的方法,比较的是两个对象的地址,而c和ch地址不同;

4,用Arrays.equals(a,b)就能比较两个数组内容;

 

String.intern()

public class Test {
	public static void main(String args[]){
		String s1 = "hello";
		String s2 = new String("hello");
		s2 = s2.intern();
		System.out.println(s1 == s2);
	}
}
true

 在常量池查找内容相同(equals())的字符串,查找不到则在常量池加入字符串。

 

String文字池(pool of literal strings)

由于字符串对象的大量使用(它是一个对象,一般而言对象总在heap分配内存),Java中为了节省内存空间和运行时间,在编译阶段就把所有的字符串文字放到一个文字池中,而运行时文字池成为常量池的一部分。文字池的好处就是该池中所有相同的字符串常量被合并,只占用一个空间。

 

以下创建了几个对象?

String A, B, C;
A = "a";
B = "b";
A = A + B;
StringBuffer D = new StringBuffer("abc");
D = D.append("567");

 

数组声明不能直接指定行数或列数,应该是在创建数组对象时定义数组的行数和列数,二维数组可以列数不同:

int iArray[][] = new int[3][4]

 

synchronized和java.util.concurrent.locks.Lock异同

同:Lock能完成synchronized所实现的所有功能;

异:Lock比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。

 

JAVA接口中对于字段会加上隐式的public,static,final,方法会加上public,abstract