1.JDK1.7以后的try-catch新格式
不需要处理关闭流的操作
package com.atguigu.java;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
JDK1.7以后try-catch的新格式
*/
public class TryCatchTest {
public static void main(String[] args) {
/*
FileInputStream fis = null;
try {
fis = new FileInputStream("a.txt");
int i = fis.read();
System.out.println(i);
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
*/
try(
//创建的流对象 --- 不需要去处理关闭流的操作了
// (正常执行还是出现异常都会在最后(try-catch结束)的时候)关闭资源
FileInputStream fis = new FileInputStream("a.txt");
){
int i = fis.read();
System.out.println(i);
}catch (Exception e){
e.printStackTrace();
}
}
}
2.获取Class对象的四种方式
方式:类名.class、对象名.getClass、Class.forName(“全类名”)- 最多-更灵活
package com.atguigu.java4;
import org.junit.Test;
/*
获取Class对象的四种方式
*/
public class ClassTest {
@Test
public void test() throws ClassNotFoundException {
Person p = new Person();
//方式一:类名.class
Class clazz = Person.class;
//方式二:对象名.getClass();
Class clazz2 = p.getClass();
//方式三 :Class.forName("全类名") - 最多 - 更灵活
Class clazz3 = Class.forName("com.atguigu.java4.Person");
//方式四 :类加载器.loadClass("全类名") - 了解
ClassLoader classLoader = this.getClass().getClassLoader();
Class clazz4 = classLoader.loadClass("com.atguigu.java4.Person");
System.out.println(clazz == clazz2 && clazz3 == clazz4);
}
@Test
public void test2() throws ClassNotFoundException {
//在调用方法时一定传一个必须存在的类
//通过流读取配置文件 --- 配置文件中的内容修改是不会影响代码本身
String s = "读取配置文件";
set(s);
}
/*
通用模板 : 要求设计一个方法给某一个类创建对象并给所有属性赋值
*/
public void set(String s) throws ClassNotFoundException {
//创建对象并给所有属性赋值
Class clazz = Class.forName(s);
//创建对象
}
}
3.通过反射可以获取类中的所有结构
给私有属性赋值 、 调用私有方法、 获取构造器 创建对象
package com.atguigu.java4;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/*
通过反射可以获取类中所有的结构
*/
public class ReflectTest {
public static void main(String[] args) throws Exception {
Person p = new Person();
//通过反射 - 给私有属性赋值
Class clazz = p.getClass();
Field id = clazz.getDeclaredField("id");
id.setAccessible(true);
id.set(p,20);
p.show();
//通过反射 - 调用私有方法
Method method = clazz.getDeclaredMethod("say");
method.setAccessible(true);
method.invoke(p);//调用了私有方法
//通过反射 获取私有构造器 创建对象
}
}
4.通过反射获得属性—— 获取所以属性
可以获取所有属性 和 获取指定的属性
package com.atguigu.java5;
import org.junit.Test;
import java.lang.reflect.Field;
public class ReflectTest {
/*
通过反射获取属性 - 获取所有属性
*/
@Test
public void test(){
//获取Class对象
Class clazz = Student.class;
//获取属性---获取的是本类及父类中所有public修饰的属性
Field[] fields = clazz.getFields();
//遍历
for (Field field : fields) {
System.out.println(field);
}
System.out.println("===============================================");
//获取本类中所有属性
Field[] declaredFields = clazz.getDeclaredFields();
//遍历
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
}
/*
通过反射获取属性 - 获取指定的属性
*/
@Test
public void test2() throws Exception {
Student s = new Student();
//1.获取Class对象
Class clazz = Student.class;
//2.获取指定属性 - public修饰的
Field sidPublic = clazz.getField("sidPublic");
//给属性赋值
/*
set(Object obj, Object value)
obj : 给哪个对象中的该属性赋值
value : 赋值的内容
*/
sidPublic.set(s,20);//给s对象中的sidPublic赋值
s.studentShow();
}
/*
通过反射获取属性 - 获取指定的属性
*/
@Test
public void test3() throws Exception {
Student s = new Student();
//1.获取Class对象
Class clazz = Student.class;
//2.获取指定属性 - 可以获取任意权限修饰符修饰的属性
Field sidPrivate = clazz.getDeclaredField("sidPrivate");
//授权 - 允许访问
sidPrivate.setAccessible(true);
//给属性赋值
/*
set(Object obj, Object value)
obj : 给哪个对象中的该属性赋值
value : 赋值的内容
*/
sidPrivate.set(s,30);//给s对象中的sidPrivate赋值
s.studentShow();
}
}
5.通过反射获取方法
获取所有的方法 和指定的方法 methods 和stestPublic
package com.atguigu.java5;
import org.junit.Test;
import java.lang.reflect.Method;
public class ReflectTest2 {
/*
通过反射获取方法 - 获取所有的
*/
@Test
public void test(){
//1.获取Class对象
Class clazz = Student.class;
//2.获取方法-获取本类及父类中所有public修饰的方法
Method[] methods = clazz.getMethods();
//3.遍历
for (Method method : methods) {
System.out.println(method);
}
System.out.println("======================================");
//获取本类中所有的方法
Method[] declaredMethods = clazz.getDeclaredMethods();
//遍历
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
}
/*
通过反射获取方法 - 获取指定的方法
*/
@Test
public void test2() throws Exception {
Student s = new Student();
//1.获Class对象
Class clazz = Student.class;
//2.获取指定的方法 - public修饰的方法
Method stestPublic = clazz.getMethod("stestPublic");
//3.调用方法
/*
invoke(Object obj, Object... args)
obj : 对象名-通过哪个对象调用该方法
args : 实参
*/
stestPublic.invoke(s);
System.out.println("======================================");
//获取指定的方法- public修饰的方法
/*
getMethod(String name, Class<?>... parameterTypes)
name : 方法的名字
parameterTypes : 形参类型的运行时类
*/
Method sdemoPublic = clazz.getMethod("sdemoPublic", String.class,int.class);
//调用方法
/*
invoke(Object obj, Object... args)
obj : 对象名-通过哪个对象调用该方法
args : 实参
*/
sdemoPublic.invoke(s,"xiaolongge",30);
}
@Test
public void test3() throws Exception {
Student s = new Student();
//1.获取Class对象
Class clazz = Student.class;
//2.获取指定的方法 - 任意权限修饰符修饰的方法
Method declaredMethod = clazz.getDeclaredMethod("srunPrivate");
//3.授权-允许访问
declaredMethod.setAccessible(true);
//4.调用方法
declaredMethod.invoke(s);
}
}
6.通过反射获取构造器
获取构造器和没有获取构造器直接造对象
package com.atguigu.java5;
import org.junit.Test;
import java.lang.reflect.Constructor;
public class ReflectTest3 {
/*
通过反射获取构造器
*/
@Test
public void test() throws Exception {
Class clazz = Employee.class;
//获取构造器
/*
getDeclaredConstructor(Class<?>... parameterTypes) :获取指定构造器(任意权限修饰符修饰的)
parameterTypes : 形参的类型
*/
Constructor declaredConstructor = clazz.getDeclaredConstructor(int.class);
//授权
declaredConstructor.setAccessible(true);
//创建对象
/*
newInstance(Object ... initargs) : 创建对象
initargs :实参
*/
Employee e = (Employee) declaredConstructor.newInstance(20);
}
/*
通过反射创建对象 :没有获取构造器直接造对象
*/
@Test
public void test2() throws InstantiationException, IllegalAccessException {
Class clazz = Employee.class;
//直接通过空参构造器造对象 --- 如果该类没有空参构造器就不能这样子造对象(需要先获取构造器再造对象)
clazz.newInstance();
}
/*
通过反射获取父类,接口
*/
@Test
public void test3(){
Class clazz = Employee.class;
//获取父类 -- 有了父类就可以获取父类中的方法 属性 构造器 父类的父类
Class superclass = clazz.getSuperclass();
System.out.println(superclass);
//获取接口
Class[] interfaces = clazz.getInterfaces();
for (Class anInterface : interfaces) {
System.out.println(anInterface);
}
}
}
7.获取属性的详细信息
package com.atguigu.java5;
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class ReflectTest4 {
/*
获取属性的详细信息
*/
@Test
public void test(){
Class clazz = Dog.class;
//获取所有的属性- 本类中所有的
Field[] declaredFields = clazz.getDeclaredFields();
//遍历
for (Field f : declaredFields) {
//获取权限修饰符
int modifiers = f.getModifiers();
System.out.print(Modifier.toString(modifiers) + " ");
//获取类型
Class type = f.getType();
System.out.print(type + " ");
//获取名字
String name = f.getName();
System.out.print(name);
System.out.println();
}
}
}
8.哪些情况会导致类的初始化 和 哪些使用类的操作不会导致类的初始化
导致类的初始化
1.主方法所在的类
2.第一次使用就是在new 此时没有初始化
3.调用某个类的静态成员 且没有初始化
4.子类初始化时父类没有初始化,先初始化父类
5.反射操作某个类时 如果类没有初始化也会导致初始化
不会导致初始化
1.某个类的静态常量
2.通过子类调用父类静态变量 方法 只会导致父类初始化
3.用某个类型声明数组并创建对象时, 不会导致这个类的初始化
package com.atguigu.java6;
/*
哪些情况会导致类的初始化
(1)运行主方法所在的类,要先完成类初始化,再执行main方法
(2)第一次使用某个类型就是在new它的对象,此时这个类没有初始化的话,先完成类初始化再做实例初始化
(3)调用某个类的静态成员(类变量和类方法),此时这个类没有初始化的话,先完成类初始化
(4)子类初始化时,发现它的父类还没有初始化的话,那么先初始化父类
(5)通过反射操作某个类时,如果这个类没有初始化,也会导致该类先初始化
Class.forName("com.atguigu.java6.SupA");
4、哪些使用类的操作不会导致类的初始化?
(1)使用某个类的静态的常量(static final)
(2)通过子类调用父类的静态变量,静态方法,只会导致父类初始化,不会导致子类初始化,即只有声明静态成员的类才会初始化
(3)用某个类型声明数组并创建数组对象时,不会导致这个类初始化
*/
class SupA{
static {
System.out.println("SupA类初始化");
}
static int id = 10;
public static final int AGE = 20;
}
class SubA extends SupA{
static {
System.out.println("SubA类初始化");
}
}
public class ClassInitTest {
static {
System.out.println("main方法所在的类");
}
public static void main(String[] args) throws ClassNotFoundException {
System.out.println("aa");
System.out.println("=================");
// new SupA();
// new SupA();
System.out.println("==============");
//System.out.println(SupA.id);
System.out.println("===============");
// new SubA();
System.out.println("==================");
//Class clazz = SupA.class;
// Class.forName("com.atguigu.java6.SupA");
//对象名.getClass()
System.out.println("==================");
//System.out.println(SupA.AGE);
System.out.println("====================");
// System.out.println(SubA.id);
System.out.println("====================");
SupA[] s = new SupA[5];
}
}
9.类加载器
双亲委派 :当类加载时应用程序类加载器先调用父类-扩展类加载器进行调用
扩展类加载器再调用父类-引导类加载器加载
引导类加载器只加载核心类库的类,如果该类是核心类库的类则加载否则不加载由儿子加载。
扩展类加载器只加载jre/lib/ext中的类。如果该类是jre/lib/ext中的类则加载否则由儿子加载。
应用程序类加载器直接加载。
package com.atguigu.java6;
import org.junit.Test;
/*
类加载器
双亲委派 :当类加载时应用程序类加载器先调用父类-扩展类加载器进行调用
扩展类加载器再调用父类-引导类加载器加载
引导类加载器只加载核心类库的类,如果该类是核心类库的类则加载否则不加载由儿子加载。
扩展类加载器只加载jre/lib/ext中的类。如果该类是jre/lib/ext中的类则加载否则由儿子加载。
应用程序类加载器直接加载。
*/
public class ClassLoaderTest {
@Test
public void test() throws ClassNotFoundException {
//获取类的运行时类的对象(Class对象)
//自定义的类用的类加载器 - AppClassLoader(应用程序类加载器)
Class clazz = Class.forName("com.atguigu.java6.A");
ClassLoader classLoader = clazz.getClassLoader();
System.out.println(classLoader);
classLoader = classLoader.getParent();//ExtClassLoader(扩展类加载器)
System.out.println(classLoader);
classLoader = classLoader.getParent();
System.out.println(classLoader);//null -- 引导类加载器(不是Java语言实现的)
}
@Test
public void test2() throws ClassNotFoundException {
//获取类的运行时类的对象(Class对象)
//null -- 引导类加载器(不是Java语言实现的)
Class clazz = Class.forName("java.lang.String");
ClassLoader classLoader = clazz.getClassLoader();
System.out.println(classLoader);
}
}
10.注解与自定义注解
补充说明 不会改变结构
@Override 说明重写
@Deprecated 说明当前结构过时
@SuppressWarnings 抑制警告
package com.atguigu.java7;
/*
注解:注解用来对类中的一些结构进行补充说明 并不会改变原有的结构
系统中的注解:
@Override :用来说明当前方法是一个重写的方法
@Deprecated : 用来说明当前结构(比如:方法,属性)已经过时
@SuppressWarnings : 抑制警告(警告不是错误可以忽略)
*/
import java.util.Date;
class A{
public void show(){}
}
class B extends A{
@Deprecated
public int id;
@Override
public void show() {
super.show();
}
@Deprecated
public void say(){
}
}
public class AnnotationTest {
public static void main(String[] args) {
Date date = new Date();
date.getDate();
new B().say();
}
@SuppressWarnings("all")
public void say(){
int id = 10;
}
}
自定义注解
格式 :
权限修饰符 @interface 注解名{
}
元注解 :注解上面使用的注解(用来描述注解的注解)
@Target :用来限制自定义的注解可以用在哪些结构上
@Retention : 用来描述自定义类的注解的生命周期
SOURCE :该注解只能用在源码上---字节码文件中就没有该注解了
CLASS : 在编译阶段到运行阶段 --- 运行以后就没有该注解了(运行时拿不到此注解)
RUNTIME : 在运行阶段 (如果想要通过反射获取此注解的信息--该注解必须是RUNTIME)
注意:只要是自定义注解一定是RUNTIME
package com.atguigu.java7;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
自定义注解
格式 :
权限修饰符 @interface 注解名{
}
元注解 :注解上面使用的注解(用来描述注解的注解)
@Target :用来限制自定义的注解可以用在哪些结构上
@Retention : 用来描述自定义类的注解的生命周期
SOURCE :该注解只能用在源码上---字节码文件中就没有该注解了
CLASS : 在编译阶段到运行阶段 --- 运行以后就没有该注解了(运行时拿不到此注解)
RUNTIME : 在运行阶段 (如果想要通过反射获取此注解的信息--该注解必须是RUNTIME)
注意:只要是自定义注解一定是RUNTIME
*/
@Target(value = {ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
@interface MyAnn{
//属性 = 如果名字叫作value那么在给注解赋值时可以省略不写
String name() default "longge";//default "longge" : 设置默认值
}
class Emp{
@MyAnn(name="xiaolongge")//name="xiaolongge" :给注解中的属性赋值
int id;
// @Override
// int age;
@MyAnn //不用强制给注解中的name赋值了 - 因为name有默认值
public void show(){
}
}
public class AnnotationTest2 {
}
11.获得类、属性、方法的注解
package com.atguigu.java8;
import org.junit.Test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
public class AnnotationTest {
@Test
public void test() throws NoSuchFieldException, NoSuchMethodException {
Class clazz = Student.class;
//拿的是类上的注解
Annotation[] annotations = clazz.getAnnotations();
System.out.println(Arrays.toString(annotations));
System.out.println("====================================");
//拿属性上的注解
//获取那个属性
Field id = clazz.getField("id");
//获取属性上的注解
Annotation[] annotations1 = id.getAnnotations();
System.out.println(Arrays.toString(annotations1));
System.out.println("====================================");
//获取方法上的注解
//获取方法
Method show = clazz.getMethod("show");
//获取方法上的注解
Annotation[] annotations2 = show.getAnnotations();
System.out.println(Arrays.toString(annotations2));
}
}