1、class文件是二进制字节码文件。Java是跨平台语言,真正执行的不是二进制代码,S而是字节码。Java是跨平台的,而JVM不是跨平台的(JVM是由C语言编写的)。
2、取模的结果符号永远与被除数的符号相同,例如:5%3= 2;-5%3 = -2; 5%-3 = 2
3、String类总结:
(1)String类的equals方法是比较两个对象的每一个字符是否相等,代码如下:
/**
* Compares this string to the specified object. The result is {@code
* true} if and only if the argument is not {@code null} and is a {@code
* String} object that represents the same sequence of characters as this
* object.
*
* @param anObject
* The object to compare this {@code String} against
*
* @return {@code true} if the given object represents a {@code String}
* equivalent to this string, {@code false} otherwise
*
* @see #compareTo(String)
* @see #equalsIgnoreCase(String)
*/
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
(2)String是常量,其对象一旦创建完毕就无法改变。当使用+拼接字符串时,会生成新的 String 对象,而不是向原有的 String 对象追加内容
(3)StringPool(字符串池)
方式一:Strings = “aaa”;(采用字面值方式赋值)
1) 查找 String Pool 中是否存在“aaa”这个对象,如果不存在,则在 String Pool 中创建一个“aaa”对象,然后将 String Pool 中的这个“aaa”对象的地址返回来,赋给引用变量 s,这样 s 会指向 String Pool 中的这个“aaa”字符串对象。
2) 如果存在,则不创建任何对象,直接将 String Pool 中的这个“aaa”对象地址返回来,赋给 s 引用。
方式二:Strings = new String(“aaa”);
1) 首先在 String Pool 中查找有没有“aaa”这个字符串对象,如果有,则不在 String Pool中再去创建“aaa”这个对象了,直接在堆中(heap)中创建一个“aaa”字符串对象,然后将堆中的这个“aaa”对象的地址返回来,赋给 s 引用,导致 s 指向了堆中创建的这个“aaa”字符串对象。
2) 如果没有,则首先在 String Pool中创建一个“aaa“对象,然后再在堆中(heap)创建一个”aaa“对象,然后将堆中的这个”aaa“对象的地址返回来,赋给 s 引用,导致 s 指向了堆中所创建的这个”aaa“对象
(4)String对象的intern方法,是返回String pool中的字符串对象引用。若只有字面字符串拼接,则返回String pool中的对象引用,否则返回堆中的对象引用。
(5)测试代码:
String str1 = new String("aaa"); //堆中的对象引用,不会检查堆中是否已有该字符串对象,new就生成新的
String str2 = new String("aaa"); //堆中的对象引用
System.out.println(str1 == str2); //不同的对象引用,所以false
System.out.println("-------------------------------");
String str3 = "bbb"; //String Pool中的对象引用,首先检查String Pool中是否已有该字符串
String str4 = "bbb"; //String Pool中的对象引用
System.out.println(str3 == str4); //相同的对象引用,所以true
System.out.println("-------------------------------");
String str5 = new String("ccc"); //堆中的对象引用
String str6 = "ccc"; //String Pool中的对象引用
System.out.println(str5 == str6); //不同的对象引用,所以false
System.out.println("-------------------------------");
String s = "hello";
String s1 = "hel";
String s2 = "lo";
System.out.println(s == s1 + s2); //s:String Pool中的对象引用 s1+s2堆中的对象引用 false
System.out.println("-------------------------------");
System.out.println(s == "hel" + "lo"); //String Pool中的对象引用 true
4、new 关键字在生成对象时完成了三件事情:
a) 为对象开辟内存空间。
b) 调用类的构造方法。
c) 将生成的对象的地址返回。
5、交换两个变量值的方法:
int a = 3;
int b = 4;
//方法一:交换两个变量值
a = a + b;
b = a - b;
a = a - b;
//方法二:
int x = a ;
a = b;
b = x;
6、random.nextInt(n) 生成0(包含)到n(不包含)之间的随机数。例如要生成10-50之间的随机数,则可这样实现:random(41) + 10
7、关于 Object 类的 equals 方法的特点
a) 自反性:x.equals(x)应该返回 true
b) 对称性:x.equals(y)为 true,那么y.equals(x)也为 true。
c) 传递性:x.equals(y)为 true 并且 y.equals(z)为 true,那么x.equals(z)也应该为 true。
d) 一致性:x.equals(y)的第一次调用为 true,那么x.equals(y)的第二次、第三次、第 n次调用也应该为 true,前提条件是在比较之间没有修改 x 也没有修改 y。
e) 对于非空引用 x,x.equals(null)返回 false8、关于 Object 类的 hashCode()方法的特点
a) 在 Java 应用的一次执行过程当中,对于同一个对象的 hashCode 方法的多次调用,他们应该返回同样的值(前提是该对象的信息没有发生变化)。
b) 对于两个对象来说,如果使用equals 方法比较返回 true,那么这两个对象的 hashCode值一定是相同的。
c) 对于两个对象来说,如果使用equals 方法比较返回 false,那么这两个对象的 hashCode值不要求一定不同(可以相同,可以不同),但是如果不同则可以提高应用的性能。
d) 对于 Object 类来说,不同的 Object 对象的 hashCode 值是不同的(Object 类的 hashCode值表示的是对象的地址)。
9、当使用 HashSet 时,hashCode()方法就会得到调用,判断已经存储在集合中的对象的hash code 值是否与增加的对象的 hash code 值一致;如果不一致,直接加进去;如果一致,再进行 equals 方法的比较,equals 方法如果返回 true,表示对象已经加进去了,就不会再增加新的对象,否则加进去。
10、策略模式的组成
–抽象策略角色:策略类,通常由一个接口或者抽象类实现。 (例如:Comparetor)
–具体策略角色:包装了相关的算法和行为。
– 环境角色:持有一个策略类的引用,最终给客户端调用的。 (例如TreeSet)
11、HashMap 底层维护一个数组,我们向 HashMap 中所放置的对象实际上是存储在该数组当中。当向 HashMap 中 put 一对键值时,它会根据 key 的 hashCode 值计算出一个位置,该位置就是此对象准备往数组中存放的位置。如果该位置没有对象存在,就将此对象直接放进数组当中;如果该位置已经有对象存在了,则顺着此存在的对象的链开始寻找(Entry 类有一个 Entry 类型的 next 成员变量,指向了该对象的下一个对象),如果此链上有对象的话,再去使用 equals 方法进行比较,如果对此链上的某个对象的 equals 方法比较为 false,则将该对象放到数组当中,然后将数组中该位置以前存在的那个对象链接到此对象的后面。
12、负载因子(loadfactor):当数组容量的占用比例超过负载因子时,数组就会扩容。
13、所谓泛型:就是变量类型的参数化。
public class GenericFoo<T>
{
private T foo;
public void setFoo(T foo)
{
this.foo = foo;
}
public T getFoo()
{
return foo;
}
}
14、在定义泛型类别时,预设可以使用任何的类型来实例化泛型类型中的类型,但是 如果想要限制使用泛型类别时 , 只能用某个特定类型或者是其子类型才能实例化该类型时 , 可以在定义类型时 , 使用 extends 关键字指定这个类型必须是继承某个类 , 或者实现某个接口。当没有指定泛型继承的类型或接口时,默认使用T extends Object,所以默认情况下任何类型都可以作为参数传入。
15、foo1 是不能赋值foo2的,GenericFoo<Integer>,泛型已成为类型的一部分。GenericFoo<Integer>foo1 = null;GenericFoo<Boolean> foo2 = null; 那么 foo1 就只接受GenericFoo<Integer>的实例,而foo2只接受GenericFoo<Boolean>的实例。
16、?用在指定引用类型(指向泛型类型可变)时,使用时限定。T用在定义类时,也可用在定义引用类型(指向泛型类型确定)时。現在您有這麼一個需求,您希望有一個參考名称foo可以接受所有下面的实例 foo = new GenericFoo<ArrayList>();foo =new GenericFoo<LinkedList>();简单的说,实例化类型持有者时,它必須是实现List的类别或其子类别,要定义这样一个名称,您可以使用 ‘?’ 通配字元,并使用“extends”关键字限定类型持有者的型态。
GenericFoo<? extends List> foo = null;
foo = new GenericFoo<ArrayList>();
foo = new GenericFoo<LinkedList>();
17、使用<?>或是<? extends SomeClass>的声明方式,意味著 您只能通过该名称來取得所参考实例的信息,或者是移除某些信息,但不能增加它的信息,因为只知道当中放置的是SomeClass的子类,但不确定是什么类的实例,编译器不让您加入信息,理由是,如果可以加入信息的話,那么您就得記得取回的实例是什么类型,然后转换为原來的类型方可进行操作,这就失去了使用泛型的意义。
若? extends Object,则可简写为?
18、Integer类有一个缓存,它会缓存介于-128~127 之间的整数。
public class IntegerTest {
public static void main(String[] args) {
Integer int1 = 200;
Integer int2 = 200;
if(int1 == int2) {
System.out.println("int1 == int2");
} else {
System.out.println("int1 != int2");
}
}
}
值为100时,为true;值为200时,为false。
19、可变参数使程序员可以声明一个接受可变数目参数的方法。注意,可变参数必须是方法声明中的最后一个参数。
public class TestArgs {
public static int sum(int... nums) { //必须使用三个点表示可变参数
//三个点等价于数组,此处定义为三个点,调用时即可传入数组,又可传多个参数
int sum = 0;
for(int num : nums) {
sum +=num;
}
return sum;
}
public static void main(String[] args) {
int result = sum(1, 2);
System.out.println(result);
result = sum(1, 2, 3, 4);
System.out.println(result);
}
}
20、可变参数:可变参数本质上就是一个数组,对于某个声明了可变参数的方法来说,我们既可以传递离散的值,也可以传递数组对象。但如果将方法中的参数定义为数组,那么只能传递数组对象而不能传递离散的值。可变参数必须要作为方法参数的最后一个参数,即一个方法不可能具有两个或两个以上的可变参数。
21、JDK1.5加入了一个全新类型的“类”-枚举类型。为此JDK1.5引入了一个新关键字enum. 我们可以这样来定义一个枚举类型。
public enum Color {
Red,
White,
Blue
}
然后可以这样来使用Color myColor = Color.Red
22、枚举类型还提供了两个有用的静态方法values()和valueOf(). 我们可以很方便地使用它们,例如
for (Color c : Color.values())
System.out.println(c);
23、switch后面可跟short,byte,char,int,枚举。例如:
public class EnumTest {
public static void doOpt(OptConstant optConstant) {
switch(optConstant) {
case TURN_LEFT :
System.out.println("向左转");
break;
case TURN_RIGHT :
System.out.println("向右转");
break;
case SHOOT :
System.out.println("射击");
break;
}
}
public static void main(String[] args) {
doOpt(OptConstant.SHOOT);
}
}
enum OptConstant {
TURN_LEFT, TURN_RIGHT, SHOOT; //分号可有可无
}
24、 定义枚举类型时本质上就是在定义一個类别,只不过很多细节由编译器帮您完成了,所以某些程度上, enum 关键字的作用就像是 class 或 interface 。我们所定义的每个枚举类型都继承自 java.lang.Enum 类,枚举中的每个枚举成员默认都是 public static final 的。而 每个枚举的成员其实就是您定义的枚举类型的一個实例( Instance ) 。换句话说,当定义了一个枚举类型后,在编译时刻就能确定该枚举类型有几个实例,分别是什么。在运行期间我们无法再使用该枚举类型创建新的实例了,这些实例在编译期间就已经完全确定下来了。
valueOf 方法将一个字符串转化为枚举类型值。
25、EnumSet举例
(一)
enum FontConstant {
Plain, Bold, Italicl, Hello;
}
public class EnumSetDemo {
public static void main(String[] args) {
//of方法定义EnumSet所包含的枚举成员
EnumSet<FontConstant> enumSet = EnumSet.of(FontConstant.Plain, FontConstant.Bold);
showEnumSet(enumSet);
System.out.println("--------------------");
//complementOf方法包含互补的枚举成员
EnumSet<FontConstant> complementSet = EnumSet.complementOf(enumSet);
showEnumSet(complementSet);
}
public static void showEnumSet(EnumSet<FontConstant> enumSet) {
//遍历EnumSet成员
for(Iterator<FontConstant> iterator = enumSet.iterator(); iterator.hasNext();) {
System.out.println(iterator.next());
}
}
}
(二)
public class EnumSetDemo2 {
public static void main(String[] args) {
//noneOf方法用来创建一个空的enum set,需指定该set存放的枚举类型
EnumSet<FontConstant> enumSet = EnumSet.noneOf(FontConstant.class);
enumSet.add(FontConstant.Plain);
}
public static void showEnumSet(EnumSet<FontConstant> enumSet) {
for(Iterator<FontConstant> iterator = enumSet.iterator(); iterator.hasNext();) {
System.out.println(iterator.next());
}
}
(三)EnumSet.copyOf(Collection c) 将List中的枚举成员取出,存入到Enumset中