JAVA部分语法注意点笔记

1.类成员变量有默认初始值,局部变量必须初始化

2.super()必须出现在构造函数的第一句

3.多态:继承,然后覆盖方法;成员变量不能多态

4.父类对象 isinstanceof 子类对象 返回 True

5.final修饰的类不能被继承,修饰的方法不能被重写,修饰的变量不能被改变

6.程序中成员变量赋值的执行顺序:
(1)声明成员变量的默认初始化
(2)显式初始化、多个初始化块依次被执行(同级别下按先后顺序执行)
(3)构造器再对成员进行初始化操作
(4)通过”对象.属性”或”对象.方法”的方式,可多次给属性赋值

7.一个类中初始化块若有修饰符,则只能被static修饰,称为静态代码块(static block),当类被载入时,类属性的声明和静态代码块先后顺序被执行,且只被执行一次。
static块通常用于初始化static ()属性
class Person {
	public static int total;
	static {
	        total = 100;//为total赋初值 
	}
	…… //其它属性或方法声明
 }

8.非静态代码块:没有static修饰的代码块
       1.可以有输出语句。
       2.可以对类的属性、类的声明进行初始化操作。
       3.可以调用静态的变量或方法。
       4.若有多个非静态的代码块,那么按照从上到下的顺序依
           次执行。
       5.每次创建对象的时候,都会执行一次。且先于构造器执行
静态代码块:用static 修饰的代码块
     1.可以有输出语句。
     2.可以对类的属性、类的声明进行初始化操作。
     3.不可以对非静态的属性初始化。即:不可以调用非静态的属
         性和方法。
    4.若有多个静态的代码块,那么按照从上到下的顺序依次执行。
    5.静态代码块的执行要先于非静态代码块。
    6.静态代码块只执行一次

9.含有抽象方法的类必须被声明为抽象类

10.不能用abstract修饰属性、私有方法、构造器、静态方法、final的方法

11.接口
(1)接口中的所有成员变量都默认是由public static final修饰的。
(2)接口中的所有抽象方法都默认是由public abstract修饰的。
(3)接口中没有构造器。
(4)接口采用多继承机制

12.Java 8中关于接口的改进
Java 8中,你可以为接口添加静态方法和默认方法。从技术角度来说,这是完全合法的,只是它看起来违反了接口作为一个抽象定义的理念。
(1)静态方法:使用 static 关键字修饰。可以通过接口直接调用静态方法,并执行其方法体。我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像Collection/Collections或者Path/Paths这样成对的接口和类。
(2)默认方法:默认方法使用 default 关键字修饰。可以通过实现类对象来调用。我们在已有的接口中提供新方法的同时,还保持了与旧版本代码的兼容性。
比如:java 8 API中对Collection、List、Comparator等接口提供了丰富的默认方法。
public interface AA {
       double PI = 3.14;

	public default void method() {
		System.out.println("北京");
	}

	default String method1() {
		return "上海";
	}

	public static void method2() {
		System.out.println(“hello lambda!");
	}
}

13.接口冲突的解决方式
比如有个类实现了两个接口,那两个接口都有getName方法,那么在本类中如何解决冲突?
class Test implements IntfaceA,InterfaceB{
	public String getName(){
		return InterfaceA.super.getName();
	}
}

14.内部类可以使用外部类的私有数据,因为它是外部类的成员,同一个类的成员之间可相互访问。而外部类要访问内部类中的成员需要:内部类.成员或者内部类对象.成员。

15.和外部类不同,Inner class可声明为privateprotected;
Inner class 可以声明为static的,但此时就不能再使用外层类的非static的成员变量;

16.Inner class作为类:
可以声明为abstract类 ,因此可以被其它的内部类继承
【注意】非static的内部类中的成员不能声明为static的,只有在外部类或static的内部类中才可声明static成员。

17.匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
new 父类构造器(实参列表)|实现接口(){
    //匿名内部类的类体部分
}
18.匿名内部类举例
interface  A{
	public  abstract void fun1();
}
public class Outer{
	public static void main(String[] args) {
		new Outer().callInner(new A(){
               //接口是不能new但此处比较特殊是子类对象实现接口,只不过没有为对象取名
			public void fun1() {
				System.out.println(“implement for fun1");
			}
		});// 两步写成一步了
	}
	public void callInner(A a) {
		a.fun1();
	}
}  

19.创建用户自定义异常类
class MyException extends Exception {
   	static final long serialVersionUID = 1L;
	private int idnumber;
 	public MyException(String message, int id) {
		super(message);
		this.idnumber = id;
 	} 
	public int getId() {
		return idnumber;
 	}
}

20.枚举类的属性
枚举类对象的属性不应允许被改动, 所以应该使用 private final 修饰
枚举类的使用 private final 修饰的属性应该在构造器中为其赋值
若枚举类显式的定义了带参数的构造器, 则在列出枚举值时也必须对应的传入参数

21.自定义 Annotation(注解)
定义新的 Annotation 类型使用 @interface 关键字
Annotation 的成员变量在 Annotation 定义中以无参数方法的形式来声明. 其方法名和返回值定义了该成员的名字和类型. 
可以在定义 Annotation 的成员变量时为其指定初始值, 指定成员变量的初始值可使用 default 关键字
public @interface MyAnnotation{
	       String name() default “atguigu";
        }
没有成员定义的 Annotation 称为标记; 包含成员变量的 Annotation 称为元数据 Annotation

22.StringBuffer类
java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删。
很多方法与String相同,但StringBuffer是可变长度的。
StringBuffer是一个容器。

23.自定义泛型类
class Person<T>{
	//使用T类型定义变量
	private T info;
	//使用T类型定义一般方法
	public T getInfo(){
		return info;
	}
	public void setInfo(T info){
		this.info = info;
	}

//使用T类型定义构造器
public Person(){}
public Person(T info){
	this.info = info;
}
//static的方法中不能声明泛型
//public static void show(T t){
//}
//不能在try-catch中使用泛型定义
//try{}
//catch(MyException<T>  ex){}		
}

24.对于泛型方法
方法,也可以被泛型化,不管此时定义在其中的类是不是泛型类。在泛型方法中可以定义泛型参数,此时,参数的类型就是传入数据的类型。

泛型方法的格式:
[访问权限]  <泛型>  返回类型  方法名([泛型标识 参数名称])  抛出的异常

public class DAO {
	
	public <E>  E get(int id, E e){
		
		E result = null;
		
		return result;
	}}

25.通配符的使用
(1)使用类型通配符:? 
比如:List<?>   ,Map<?,?>
List<?>是List<String>、List<Object>等各种泛型List的父类。
(2)读取List<?>的对象list中的元素时,永远是安全的,因为不管list的真实类型是什么,它包含的都是Object。
(3)写入list中的元素时,不行。因为我们不知道c的元素类型,我们不能向其中添加对象。
唯一的例外是null,它是所有类型的成员。

将任意元素加入到其中不是类型安全的:
Collection<?> c = new ArrayList<String>();
c.add(new Object()); // 编译时错误
因为我们不知道c的元素类型,我们不能向其中添加对象。
        add方法有类型参数E作为集合的元素类型。我们传给add的任何参数都必须是一个未知类型的子类。因为我们不知道那是什么类型,所以我们无法传任何东西进去。
唯一的例外的是null,它是所有类型的成员。

另一方面,我们可以调用get()方法并使用其返回值。返回值是一个未知的类型,但是我们知道,它总是一个Object

26.有限制的通配符
<?>
允许所有泛型的引用调用
举例:
<? extends Number>     (无穷小 , Number]
只允许泛型为Number及Number子类的引用调用

<? super Number>      [Number , 无穷大)
只允许泛型为Number及Number父类的引用调用

<? extends Comparable>
只允许泛型为实现Comparable接口的实现类的引用调用

public static void printCollection3(Collection<? extends Person> coll){
	//Iterator只能用Iterator<?>或Iterator<? extends Person>.why?
	Iterator<?> iterator  = coll.iterator();
	while(iterator.hasNext()){
		System.out.println(iterator.next());
}   }
public static void printCollection4(Collection<? super Person> coll){
	Iterator<?> iterator  = coll.iterator();
	while(iterator.hasNext()){
		System.out.println(iterator.next());
}   }

27.程序中打开的文件 IO 资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以应该显式关闭文件 IO 资源。

28.缓冲流要“套接”在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法
对于输出的缓冲流,写出的数据会先在内存中缓存,使用flush()将会使内存中的数据立刻写出
BufferedReader br = null;
BufferedWriter bw = null;		
try {
	//step1:创建缓冲流对象:它是过滤流,是对节点流的包装
	br = new  BufferedReader(new FileReader("d:\\IOTest\\source.txt"));
	bw = new BufferedWriter(new FileWriter("d:\\IOTest\\destBF.txt"));
	String str = null;
	while ((str = br.readLine()) != null) { //一次读取字符文本文件的一行字符
		bw.write(str); //一次写入一行字符串
		bw.newLine();  //写入行分隔符
	} bw.flush();  //step2:刷新缓冲区
} catch (IOException e) {
	e.printStackTrace();
} 
finally {
	// step3: 关闭IO流对象
	try {
		if (bw != null) {
			bw.close();  //关闭过滤流时,会自动关闭它所包装的底层节点流
		}
	} catch (IOException e) {
		e.printStackTrace();
	}
try {
	if (br != null) {
		br.close();
	} 
} 
catch (IOException e) {
	e.printStackTrace();
}  

29.序列化:用ObjectOutputStream类保存基本类型数据或对象的机制
反序列化:用ObjectInputStream类读取基本类型数据或对象的机制
对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象
序列化的好处在于可将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原

30.对象的序列化
凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:
private static final long serialVersionUID;
serialVersionUID用来表明类的不同版本间的兼容性
如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的源代码作了修改,serialVersionUID 可能发生变化。故建议,显示声明

简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)

31.序列化的使用例子
序列化:将对象写入到磁盘或者进行网络传输。
要求对象必须实现序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test3.txt"));
Person p = new Person("韩梅梅",18,"中华大街",new Pet());
oos.writeObject(p);
oos.flush();
oos.close();
//反序列化:将磁盘中的对象数据源读出。
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test3.txt"));
Person p1 = (Person)ois.readObject();
System.out.println(p1.toString());
ois.close();

31.转换流
InputStreamReader:用于将字节流中读取到的字节按指定字符集解码成字符。需要和InputStream“套接”。
OutputStreamWriter:用于将要写入到字节流中的字符按指定字符集编码成字节。需要和OutputStream“套接”。
public void testMyInput() throws Exception{
    FileInputStream fis = new FileInputStream("dbcp.txt");
    FileOutputStream fos = new FileOutputStream("dbcp5.txt");

    InputStreamReader isr = new InputStreamReader(fis,"GBK");
    OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");

    BufferedReader br = new BufferedReader(isr);
    BufferedWriter bw = new BufferedWriter(osw);

    String str = null;
    while((str = br.readLine()) != null){
        bw.write(str);
        bw.newLine();
        bw.flush();
}    bw.close();  br.close();}

32.Class 类
对象照镜子后可以得到的信息:某个类的属性、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象。一个 Class 对象包含了特定某个类的有关信息。
Class本身也是一个类
Class 对象只能由系统建立对象
一个类在 JVM 中只会有一个Class实例 
一个Class对象对应的是一个加载到JVM中的一个.class文件
每个类的实例都会记得自己是由哪个 Class 实例所生成
通过Class可以完整地得到一个类中的完整结构 

33.反射的应用举例
String str = "test4.Person";
Class clazz = Class.forName(str);
Object obj = clazz.newInstance();
Field field = clazz.getField("name");
field.set(obj, "Peter");
Object obj2 = field.get(obj);
System.out.println(obj2);

34.创建运行时类的对象
//1.根据全类名获取对应的Class对象
String name = “atguigu.java.Person";
Class clazz = null;
clazz = Class.forName(name);
//2.调用指定参数结构的构造器,生成Constructor的实例
Constructor con = clazz.getConstructor(String.class,Integer.class);
//3.通过Constructor的实例创建对应类的对象,并初始化类属性
Person p2 = (Person) 	con.newInstance("Peter",20);
System.out.println(p2);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值