2017年7月6日 上午8:03
成员式内部类-非静态:
1. 生成两个class文件
2. **Outer$Inner.class**
3. Outer.class
4. **内部类的方法和属性可以和外部类相同**
Outer.class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Outer { String name; public void method(){ } public class Inner{ int age; String name; void method(){ } } }
|
成员式内部类-静态
Outer2.class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Outer2 { String name; public void method(){ } public static class Inner{ int age; String name; void method(){ } } }
|
Test1.class
1 2 3 4 5 6 7 8 9 10 11
| public class Test1 {
public static void main(String[] args) { Outer.Inner oi = new Outer().new Inner(); Outer2.Inner oi2 = new Outer2.Inner(); }
}
|
匿名内部类
Outer3.class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class Outer3 { String name = "czh"; public void method(final int j){ int x=0; class Inner{ int age = x; String name2= name; int k = j;
void method(){ System.out.println("Inner类方法"); } } Inner in = new Inner(); in.method(); } public void method2(){
} }
|
几点说明:
1. 全局变量name 和 method()中的局部变量可以直接被内部类Inner()使用,因为:name 和 x的作用域包含内部类
2. 内部类Inner的作用域为method()方法中,所以:在method2()中声明Inner类对象是会报错的。
3. java1.8中,method(final int j )中的final可以不用加了
反射
定义:在编译时不确定哪个类被加载,而在程序运行时才加载、
探知、使用。常用于框架中,具体的不会!
反射的操作方式:
- 我们平常操作时都是对象.属性/方法,对象为主角
- 在反射中,属性(Field)方法(Method)构造(Constructor)为主角,他们去【点】,原对象对象反而作为了参数
- 并且反射还可操作private属性
- 总结:换了一种操作类和对象的方式
两种得到类的方式
- Class cla=Student.class;
- 包名+类名
- Class cla = Class.forName(“package1.Student”);
反射常用的Java 类型
- Class类—可获取类和类的成员信息
- Field类—可访问类的属性
- Method类—可调用类的方法
- Constructor类—可调用类的构造方法
使用反射的步骤:
- 导入java.lang.reflect.*
- 获得需要操作的类的Java.lang.Class对象
- 调用Class的方法获取Field、Method等对象
- 使用反射API进行操作 (设置属性、调用方法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| public class Student { private String name; private int age;
public String getName() { return name; } public void setName(String name) { this.name=name; } public int getAge() { return age; } public void setAge(int age) { this.age=age; } public String toString(){ return "name is "+name+", age is "+age; }
} ================================================
import java.lang.reflect.Field;
public class Test_Student { public static void main(String[] args) throws Exception{ Student p=new Student(); Class cla=Student.class; Field nameField=cla.getDeclaredField("name"); nameField.setAccessible(true); nameField.set(p, "Jack"); Field ageField=cla.getDeclaredField("age"); ageField.setAccessible(true); ageField.setInt(p, 20); System.out.println(p); }
} ==================================================
import java.lang.reflect.Method;
public class Test_Method { public static void main(String[] args) throws Exception{ Class cla=Student.class; Student p=new Student(); Method met1=cla.getMethod("setName", String.class); met1.invoke(p, "Jack");
Method met=cla.getMethod("getName", null); Object o=met.invoke(p, null); System.out.println(o); }
} ==================================================
import java.lang.reflect.Constructor; import java.util.Date; public class Test_Constructor { public static void main(String[] args) throws Exception{ Class cla=Date.class; Constructor cu=cla.getConstructor(long.class); Date d=(Date)cu.newInstance(1987); System.out.println(d.toString());
} }
|
一个使用反射的例子(数据库连接)
1 2 3 4 5 6
| public COnnnection getConnection() throws Exception{ Connection conn = null; Class.forName("com.mysqk.jdbc.Dirver"); conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/<Datebase>","root","123456"); syso("连接数据库成功"); }
|