inti = 5; intj = 10; System.out.println(i + ~j);A、Compilation error because”~”doesn’t operate on integers B、-5 C、-6 D、15
List list = new ArrayList(); list.add(18); list.add("lly"); for(Object obj : list){ int i = (int) obj;//此处运行后,将会报错 }上面在将“lly”转成int时,会报ClassCastException,但是在编译时却不会出错。(在我们JDK1.5之后有了泛型之后,但是没有去使用泛型来定义集合,跟上面的一样效果。),同时,这也验证了我们前面总结异常类型时所说的,ClassCastException是属于运行时异常,也即非检查性异常。 在我们使用泛型之后,可以避免不必要的转型,以及避免可能出现的ClassCastException,如下:
List<Integer> list = new ArrayList<Integer>(); list.add(18); list.add("lly"); //此时,编译时就不能通过,报错!!!泛型允许我们在创建集合时就可以指定元素类型,当加入其他数据类型时,编译不能通过。泛型只作用于编译阶段,在编译阶段严格检查类型是否匹配,类型检查通过后,JVM会将泛型的相关信息擦出掉(即泛型擦除),也就是说,成功编译过后的class文件中是不包含任何泛型信息的,泛型信息不会进入到运行时阶段。 如果像我们上面说的这样,那对于传进来的不同数据类型的对象也只会生成一个类型,而不是多种数据类型对象。下面我们可以验证一下:
class Person<T> { private T charac;//人物特征 public Person(T ch){ this.charac = ch; } public T getCharac() { return charac; } public void setCharac(T charac) { this.charac = charac; } }测试:
Person<String> p1 = new Person<String>("lly"); Person<Integer> p2 = new Person<Integer>(18); System.out.println("p1--->"+p1.getClass()); System.out.println("p2--->"+p2.getClass());打印如下: p1--->class com.scu.lly.Person p2--->class com.scu.lly.Person 可以看到,虽然我们传入了两种数据类型,但是在编译时并没有生成这两种类型,而都是Person类型,这正是因为我们上面所说的,泛型在编译通过后,确保了类型正确,此后就擦除了相关泛型信息,把所有元素都作为Person数据类型。也就是说,泛型类型在逻辑上我们可以看成是多个不同的数据类型,但是在本质上它只是同一种数据类型。
public class CommonTest { public static void main(String[] args) { Person<Number> p1 = new Person<Number>(12); Person<Integer> p2 = new Person<Integer>(18); getCharac(p1); getCharac(p2);//报错!!!编译不能通过,提示参数类型不符合 } public static void getCharac(Person<Number> person){ System.out.println(person.getCharac()); } }按照我们的想法,因为Integer 是继承自Number的,根据Java多态的特性,我们调用getCharac(p2);应该是没有问题的,但是正是因为泛型擦除的特点,导致了泛型在编译通过后被擦除了泛型类型,在运行时,JVM根本不知道有Number和Integer这两个类型存在,内存中只会有Person对象存在。这也正是上面不能编译通过的原因。 为了解决这个问题,也就是说在使用泛型的时候为了能够体现出父子关系(或者说兼容多态特性),提出了类型通配符的概念。类型通配符用 来代替参数类型,代表任何类型的父类,比如Person<>就是Person<Number>和Person<Integer>的父类了,而Person<Number>和Person<Integer>是体现不出父类关系的,现在就可以继续使用多态特性了,如下: public static void getCharac(Person<> person){ System.out.println(person.getCharac()); } 将上面的参数类型改成通配符的形式以后,我们调用getCharac(p2);就不会出错了。
public class VarTest { final int i ; public VarTest(){ //在构造方法中初始化了 i = 3; } public VarTest(int n){ //有多个构造方法,必须在每个构造方法中进行初始化 i = n; } public void doSomething() { int j; j = 1;//对于临时变量,如果这里不进行初始化,下面使用++j时编译不能通过 System.out.println(++j + i); } public static void main(String[] args) { VarTest test = new VarTest(); test.doSomething(); } }
Boolean flag = false; if(flag = true){ System.out.println(“true”); }else{ System.out.println(“false”); }A、The code fails to compile at the “if” statement. B、An exception is thrown at run-time at the “if” statement. C、The text“true” is displayed. D、The text“false”is displayed. E、Nothing is displayed.
public class test{ static{ intx=5; } static int x,y; public static void main(String args[]){ x--; myMethod( ); System.out.println(x+y+ ++x); } public static void myMethod( ){ y=x++ + ++x; } }A、compiletime error B、prints:1 C、prints:2 D、prints:3 E、prints:7 F、prints:8
public static void main (String[] args) { String classFile = "com. jd. ". replaceA11(".", "/") + "MyClass.class"; System.out.println(classFile); }A、com. jd B、com/jd/MyClass.class C、///////MyClass.class D、com.jd.MyClass
int b = 127; System.out.println(b); b = b++; System.out.println(b);A、127 B、128
inti=0; Integer j = newInteger(0); System.out.println(i==j); System.out.println(j.equals(i));
A、true,false B、true,true C、false,true D、false,false E、对于不同的环境结果不同 F、程序无法执行
byte b1=1,b2=2,b3,b6; final byteb4=4,b5=6; b6=b4+b5; b3=(b1+b2); System.out.println(b3+b6);关于上面代码片段叙述正确的是()
A、输出结果:13 B、语句:b6=b4+b5编译出错 C、语句:b3=b1+b2编译出错 D、运行期抛出异常
A、不执行finally代码 B、return前执行 C、return后执行正确答案:C finally语句是在try(或catch)的return语句执行之后,return返回之前执行。过程如下:在try中如果有return语句,他会首先检测是否有fianlly,如果有的话,就保存try中return要返回的值,然后执行finally中的方法,如果fianlly没有返回值,则finally方法执行完毕之后,返回执行try中的return方法,他会取出之前保存的return值,进行返回。 如下例子:
public static void main(String[] args) { intk = f_test(); System.out.println(k); } public static int f_test(){ inta = 0; try{ a = 1; returna; } finally{ System.out.println("It is in final chunk."); a = 2; returna; } }输出: It is in final chunk. 2
// 所有整数 int, short,long,byte都可以用二进制表示 // An 8-bit 'byte' value: byte aByte = (byte) 0b00100001; // A 16-bit 'short' value: short aShort = (short) 0b1010000101000101; // Some 32-bit 'int' values: intanInt1 = 0b10100001010001011010000101000101; intanInt2 = 0b101; intanInt3 = 0B101; // The B can be upper or lower case. // A 64-bit 'long' value. Note the "L" suffix: long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L; // 二进制在数组等的使用 final int[] phases = { 0b00110001, 0b01100010, 0b11000100, 0b10001001, 0b00010011, 0b00100110, 0b01001100, 0b10011000 };
String str = "a"; switch (str) { case "a": System.out.println("a---"); break; case "b": System.out.println("b---"); break; }注意:在把字符串传进Switch case之前,别忘了检查字符串是否为Null。
long creditCardNumber = 1234_5678_9012_3456L; long socialSecurityNumber = 999_99_9999L; float pi = 3.14_15F; long hexBytes = 0xFF_EC_DE_5E; long hexWords = 0xCAFE_BABE; long maxLong = 0x7fff_ffff_ffff_ffffL; byte nybbles = 0b0010_0101; long bytes = 0b11010010_01101001_10010100_10010010; //float pi1 = 3_.1415F; // Invalid; cannot put underscores adjacent to a decimal point //float pi2 = 3._1415F; // Invalid; cannot put underscores adjacent to a decimal point //long socialSecurityNumber1= 999_99_9999_L; // Invalid; cannot put underscores prior to an L suffix //int x1 = _52; // This is an identifier, not a numeric literal int x2 = 5_2; // OK (decimal literal) //int x3 = 52_; // Invalid; cannot put underscores at the end of a literal int x4 = 5_______2; // OK (decimal literal) //int x5 = 0_x52; // Invalid; cannot put underscores in the 0x radix prefix //int x6 = 0x_52; // Invalid; cannot put underscores at the beginning of a number int x7 = 0x5_2; // OK (hexadecimal literal) //int x8 = 0x52_; // Invalid; cannot put underscores at the end of a number int x9 = 0_52; // OK (octal literal) int x10 = 05_2; // OK (octal literal) //int x11 = 052_; // Invalid; cannot put underscores at the end of a number
BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { br.close(); }而1.7之后我们可以使用这种形式:
try (BufferedReader br = new BufferedReader(new FileReader(path)) { return br.readLine(); }直接在try中进行声明,跟finally里面的关闭资源类似; 按照声明逆序关闭资源。这些资源都需要实现java.lang.AutoCloseable接口的资源。
Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法,示例如下:
代码如下:interface Formula { double calculate(int a); default double sqrt(int a) { return Math.sqrt(a); } }Formula接口在拥有calculate方法之外同时还定义了sqrt方法,实现了Formula接口的子类只需要实现一个calculate方法,默认方法sqrt将在子类上可以直接使用。
Formula formula = new Formula() { @Override public double calculate(int a) { return sqrt(a * 100); } }; formula.calculate(100); // 100.0 formula.sqrt(16); // 4.0
首先看看在老版本的Java中是如何排列字符串的:
代码如下:List<String> names = Arrays.asList("peter", "anna", "mike", "xenia"); Collections.sort(names, new Comparator<String>() { @Override public int compare(String a, String b) { return b.compareTo(a); } });只需要给静态方法 Collections.sort 传入一个List对象以及一个比较器来按指定顺序排列。通常做法都是创建一个匿名的比较器对象然后将其传递给sort方法。
在Java 8 中你就没必要使用这种传统的匿名对象的方式了,Java 8提供了更简洁的语法,lambda表达式:
复制代码 代码如下: Collections.sort(names, (String a, String b) -> {Java 8 在包java.time下包含了一组全新的时间日期API。新的日期API和开源的Joda-Time库差不多,但又不完全一样,下面的例子展示了这组新API里最重要的一些部分:
Clock 时钟
Clock类提供了访问当前日期和时间的方法,Clock是时区敏感的,可以用来取代 System.currentTimeMillis() 来获取当前的微秒数。某一个特定的时间点也可以使用Instant类来表示,Instant类也可以用来创建老的java.util.Date对象。
代码如下:Clock clock = Clock.systemDefaultZone(); long millis = clock.millis(); Instant instant = clock.instant(); Date legacyDate = Date.from(instant); // legacy java.util.Date
A、throw关键字可以在方法上声明该方法要抛出的异常。 B、throws用于抛出异常对象。
C、try是用于检测被包住的语句块是否出现异常,如果有异常,则抛出异常,并执行catch语句。
D、finally语句块是不管有没有出现异常都要执行的内容。 E、在try块中不可以抛出异常
热门源码