Annotation注解
自定义注解:
//使用
//有default可以不用写出来
@Myannotation(age = 10)
public class Testannotation {
}
//自定义注解
//表示可以作用在方法和类上
@Target({ElementType.METHOD,ElementType.TYPE})
//可以保留在什么地方?运行的时候也可以保留
@Retention(RetentionPolicy.RUNTIME)
@interface Myannotation{
//定义类型和变量,有些不同
String name() default "";//default "":表示后面可以加上默认的值
int age();
int id() default 0;
String[] schools() default {"清华","所罗门"};
}
Reflection反射:
- 初步展现了,反射机制在未来框架中的使用方式
- 反射有什么用?
- 可以可以访问Class
- 可以让程序更加灵活
获取class的三种方式:
//Class.forName();
Class c = Class.forName("com.wang.Reflection.User");
//对象.getclass
String s= "abc";
Class x = s.getclass();
//属性.class也是一种方法
Class d = Date.class;
Class s = String.class;
Class i = int.class;
案例:
ReflectionTest
/**
* 初步展现了,反射机制在未来框架中的使用方式
* 反射有什么用?
* 可以可以访问Class
* 可以让程序更加灵活
*
*/
public class ReflectionTest {
public static void main(String[] args) {
FileInputStream fis=null;
// FileReader frd=null;
try {
//通过io流来加载文件
fis = new FileInputStream("src/resources/classinfo.properties");
// fis= new FileInputStream("");
//然后通过properties来储存加载的io流文件
Properties pro = new Properties();
//通过加载器load来加载文件
pro.load(fis);
//这一步里,pro就保存了配置为文件里面的信息,就可以关闭了
String classname = pro.getProperty("classname");
//因为是储存在以键值对形式存在的Map集合中,所以可以通过getProperties的健来获取他的值
//通过有反射机制来实现类的实例化
//获取类,classname是一个地址
Class c = Class.forName(classname);
//实例化了对象了
Object obj = c.newInstance();
//然后就可以通过这个对象obj来对User这个类操作
System.out.println(obj);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
User
public class User {
public User() {
System.out.println("这是User的无参数构造");
}
}
classinfo.properties
classname=com.wang.Reflection.User
缺点:
注意:使用以下通用方式的前提是:这个文件必须在类路径下
什么是类路径下?方式在src下的都是类路径下。【记住】
有一个问题:配置文件路径的问题,这种方式移植性差
换一种通用的路径:
String path = Thread.currentThread().getContextClassLoader().getResource("classinfo.properties").getPath();
获取文件的绝对路径
示例:
1.通用方式获得文件的绝对路径,移植性强
//通用方式获得文件的绝对路径,移植性强
String path = Thread.currentThread().getContextClassLoader().getResource("resources/classinfo.properties").getPath();
2.通用方式获得文件的绝对路径,以IO流的形式返回一个值,这样子在Properties这个获取加载器load的时候可以直接用**
//通用方式获得文件的绝对路径,以IO流的形式返回一个值
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("resources/classinfo.properties");
/**
* 初步展现了,反射机制在未来框架中的使用方式
* 反射有什么用?
* 可以可以访问Class
* 可以让程序更加灵活
*
*/
public class ReflectionTest {
public static void main(String[] args) {
FileInputStream fis=null;
// FileReader frd=null;
try {
// //通用方式获得路径,移植性强
// String path = Thread.currentThread().getContextClassLoader().getResource("resources/classinfo.properties").getPath();
// //通过io流来加载文件
// fis = new FileInputStream(path);
//重点、重点、重点、重点、重点、重点
//用一种更加方便的写法,后面常用的,这样子上面的两行代码就省了
//直接以流的形式返回一个值
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("resources/classinfo.properties");
//重点、重点、重点、重点、重点、重点
// fis= new FileInputStream("");
//然后通过properties来储存加载的io流文件
Properties pro = new Properties();
//通过加载器load来加载文件
pro.load(in);
//这一步里,pro就保存了配置为文件里面的信息,就可以关闭了
String classname = pro.getProperty("classname");
//因为是储存在以键值对形式存在的Map集合中,所以可以通过getProperties的健来获取他的值
//通过有反射机制来实现类的实例化
//获取类
Class c = Class.forName(classname);
//实例化了对象了
Object obj = c.newInstance();
//然后就可以通过这个对象obj来对User这个类操作
System.out.println(obj);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
资源绑定器
ResourceBundle bundle = ResourceBundle.getBundle("classinfo");
/**
* 使用资源绑定器来获取属性配置文件的内容
* 必须在类路径下面
*
*/
public class ResourcesBundleTest {
public static void main(String[] args) {
//不能加.properties后缀名
//只能绑定是.properties的文件
ResourceBundle bundle =ResourceBundle.getBundle("classinfo");
String classname = bundle.getString("classname");
System.out.println(classname);
}
}
Field类:
示例:
/**
* 通过反射机制获得类的field并且赋值
*
*/
public class ReflectionGetFieldTest {
public static void main(String[] args) throws Exception {
//正常的方法获取User
User user = new User();
user.setNo(10);
System.out.println(user.getNo());//默认调用里面的无参构造方法
//通过反射来操作
// String path = Thread.currentThread().getContextClassLoader().getResource("com.wang.Reflection.User").getPath();
Class c = Class.forName("com.wang.Reflection.User");
//然后实例化对象
Object o = c.newInstance();
//获取User中no属性Field
Field field = c.getDeclaredField("no");
//打破封装,就可以访问私有属性,在获取了某个属性之后使用
field.setAccessible(true);
//赋值
field.set(o,100);
//取值
field.get(o);
System.out.println(field.get(o));
}
}
Method类(重点):
示例:
/**
* 通过反射机制获取类的方法
*
*/
public class ReflectionGetMethodTest {
public static void main(String[] args) {
//正常的获取类的方法
User user = new User();
// if (user.UserLogin("username", "password")){
System.out.println("恭喜登陆成功");
}
user.UserLogin("username", "password");
System.out.println("===================================");
try {
//通过反射机制获取方法
//只能获取资源类型的
// String path = Thread.currentThread().getContextClassLoader().getResource("com.wang.Reflection.User").getPath();
//获取类
Class c = Class.forName("com.wang.Reflection.User");
//实例化这个类,这一步会默认调用无参构造方法
Object obj = c.newInstance();
System.out.println("===================================");
//先说明获取的是那一个方法,c.getDeclaredMethod("某个方法的名字", 类型.class,类型.class);
Method userLogin = c.getDeclaredMethod("UserLogin", String.class, String.class);
//获取了方法,就开始调用userLogin.invoke("实例化的对象", "输入的参数", "输入的参数")
Object invokeMethod = userLogin.invoke(obj, "username", "password");
//System.out.println(invokeMethod);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
Constructor类:
示例:
/**
* 通过反射机制调用构造方法
*/
public class ReflectionGetConstructorTest {
public static void main(String[] args) {
System.out.println("正常方法:");
//正常方法
User user = new User();//默认调用无参构造方法
User user1 = new User(10);//调用一个参数的构造方法
User user2 = new User(10,"wzk");//调用两个参数的构造方法
System.out.println("============================");
try {
//反射记住获取构造方法
Class c = Class.forName("com.wang.Reflection.User");
System.out.println("调用无参数的:");
//调用无参数的
//实例化对象,这一步直接调用了无参构造方法
Object o = c.newInstance();
System.out.println("==============================");
System.out.println("调用有参数的:");
//调用有参数的
//第一步:获取构造方法
Constructor constructor = c.getDeclaredConstructor(int.class, String.class);
//第二步:调用构造方法new对象
Object obj = constructor.newInstance(100, "wjj");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
反射获取一个类的父类和父接口
//反射获取一个类的父类和父接口
public class ReflectionGetClassAndInteefaceTest {
public static void main(String[] args) throws ClassNotFoundException {
Class c = Class.forName("java.lang.String");
//反射获取一个类的父类
Class superclass = c.getSuperclass();
System.out.println(superclass.getName());
//反射获取一个类的接口
Class[] interfaces = c.getInterfaces();
for (int i = 0; i <interfaces.length ; i++) {
System.out.println(interfaces[i]);
}
}
}