一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - java反射深入剖析(推薦)

java反射深入剖析(推薦)

2020-05-31 13:11jingxian JAVA教程

下面小編就為大家帶來一篇java反射深入剖析。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

本篇文章依舊采用小例子來說明,因為我始終覺的,案例驅動是最好的,要不然只看理論的話,看了也不懂,不過建議大家在看完文章之后,在回過頭去看看理論,會有更好的理解。

下面開始正文。

【案例1】通過一個對象獲得完整的包名和類名

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package Reflect;
 
/**
 * 通過一個對象獲得完整的包名和類名
 * */
class Demo{
  //other codes...
}
 
class hello{
  public static void main(String[] args) {
    Demo demo=new Demo();
    System.out.println(demo.getClass().getName());
  }
}

【運行結果】:Reflect.Demo

添加一句:所有類的對象其實都是Class的實例。

【案例2】實例化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
package Reflect;
class Demo{
  //other codes...
}
 
class hello{
  public static void main(String[] args) {
    Class<?> demo1=null;
    Class<?> demo2=null;
    Class<?> demo3=null;
    try{
      //一般盡量采用這種形式
      demo1=Class.forName("Reflect.Demo");
    }catch(Exception e){
      e.printStackTrace();
    }
    demo2=new Demo().getClass();
    demo3=Demo.class;
     
    System.out.println("類名稱  "+demo1.getName());
    System.out.println("類名稱  "+demo2.getName());
    System.out.println("類名稱  "+demo3.getName());
     
  }
}

【運行結果】:
類名稱   Reflect.Demo
類名稱   Reflect.Demo
類名稱   Reflect.Demo

【案例3】通過Class實例化其他類的對象

通過無參構造實例化對象

?
1
2
3
4
public Person(String name, int age) {
    this.age=age;
    this.name=name;
  }

然后繼續運行上面的程序,會出現:

java反射深入剖析(推薦)

所以大家以后再編寫使用Class實例化其他類的對象的時候,一定要自己定義無參的構造函數
 
【案例】通過Class調用其他類中的構造函數 (也可以通過這種方式通過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
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
package Reflect;
 
import java.lang.reflect.Constructor;
 
class Person{
   
  public Person() {
     
  }
  public Person(String name){
    this.name=name;
  }
  public Person(int age){
    this.age=age;
  }
  public Person(String name, int age) {
    this.age=age;
    this.name=name;
  }
  public String getName() {
    return name;
  }
  public int getAge() {
    return age;
  }
  @Override
  public String toString(){
    return "["+this.name+" "+this.age+"]";
  }
  private String name;
  private int age;
}
 
class hello{
  public static void main(String[] args) {
    Class<?> demo=null;
    try{
      demo=Class.forName("Reflect.Person");
    }catch (Exception e) {
      e.printStackTrace();
    }
    Person per1=null;
    Person per2=null;
    Person per3=null;
    Person per4=null;
    //取得全部的構造函數
    Constructor<?> cons[]=demo.getConstructors();
    try{
      per1=(Person)cons[0].newInstance();
      per2=(Person)cons[1].newInstance("Rollen");
      per3=(Person)cons[2].newInstance(20);
      per4=(Person)cons[3].newInstance("Rollen",20);
    }catch(Exception e){
      e.printStackTrace();
    }
    System.out.println(per1);
    System.out.println(per2);
    System.out.println(per3);
    System.out.println(per4);
  }
}

【運行結果】:

[null  0]
[Rollen  0]
[null  20]
[Rollen  20]

【案例】

返回一個類實現的接口:

?
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
package Reflect;
 
interface China{
  public static final String name="Rollen";
  public static int age=20;
  public void sayChina();
  public void sayHello(String name, int age);
}
 
class Person implements China{
  public Person() {
     
  }
  public Person(String sex){
    this.sex=sex;
  }
  public String getSex() {
    return sex;
  }
  public void setSex(String sex) {
    this.sex = sex;
  }
  @Override
  public void sayChina(){
    System.out.println("hello ,china");
  }
  @Override
  public void sayHello(String name, int age){
    System.out.println(name+" "+age);
  }
  private String sex;
}
 
class hello{
  public static void main(String[] args) {
    Class<?> demo=null;
    try{
      demo=Class.forName("Reflect.Person");
    }catch (Exception e) {
      e.printStackTrace();
    }
    //保存所有的接口
    Class<?> intes[]=demo.getInterfaces();
    for (int i = 0; i < intes.length; i++) {
      System.out.println("實現的接口  "+intes[i].getName());
    }
  }
}

【運行結果】:

實現的接口   Reflect.China

(注意,以下幾個例子,都會用到這個例子的Person類,所以為節省篇幅,此處不再粘貼Person的代碼部分,只粘貼主類hello的代碼)

【案例】:取得其他類中的父類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
class hello{
  public static void main(String[] args) {
    Class<?> demo=null;
    try{
      demo=Class.forName("Reflect.Person");
    }catch (Exception e) {
      e.printStackTrace();
    }
    //取得父類
    Class<?> temp=demo.getSuperclass();
    System.out.println("繼承的父類為:  "+temp.getName());
  }
}

【運行結果】

繼承的父類為:   java.lang.Object

【案例】:獲得其他類中的全部構造函數

這個例子需要在程序開頭添加import java.lang.reflect.*;
然后將主類編寫為:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class hello{
  public static void main(String[] args) {
    Class<?> demo=null;
    try{
      demo=Class.forName("Reflect.Person");
    }catch (Exception e) {
      e.printStackTrace();
    }
    Constructor<?>cons[]=demo.getConstructors();
    for (int i = 0; i < cons.length; i++) {
      System.out.println("構造方法: "+cons[i]);
    }
  }
}

【運行結果】:

構造方法:  public Reflect.Person()
構造方法:  public Reflect.Person(java.lang.String)

但是細心的讀者會發現,上面的構造函數沒有public 或者private這一類的修飾符

下面這個例子我們就來獲取修飾符

?
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
class hello{
  public static void main(String[] args) {
    Class<?> demo=null;
    try{
      demo=Class.forName("Reflect.Person");
    }catch (Exception e) {
      e.printStackTrace();
    }
    Constructor<?>cons[]=demo.getConstructors();
    for (int i = 0; i < cons.length; i++) {
      Class<?> p[]=cons[i].getParameterTypes();
      System.out.print("構造方法: ");
      int mo=cons[i].getModifiers();
      System.out.print(Modifier.toString(mo)+" ");
      System.out.print(cons[i].getName());
      System.out.print("(");
      for(int j=0;j<p.length;++j){
        System.out.print(p[j].getName()+" arg"+i);
        if(j<p.length-1){
          System.out.print(",");
        }
      }
      System.out.println("){}");
    }
  }
}

【運行結果】:

構造方法:  public Reflect.Person(){}
構造方法:  public Reflect.Person(java.lang.String arg1){}

有時候一個方法可能還有異常,呵呵。下面看看:

?
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
class hello{
  public static void main(String[] args) {
    Class<?> demo=null;
    try{
      demo=Class.forName("Reflect.Person");
    }catch (Exception e) {
      e.printStackTrace();
    }
    Method method[]=demo.getMethods();
    for(int i=0;i<method.length;++i){
      Class<?> returnType=method[i].getReturnType();
      Class<?> para[]=method[i].getParameterTypes();
      int temp=method[i].getModifiers();
      System.out.print(Modifier.toString(temp)+" ");
      System.out.print(returnType.getName()+" ");
      System.out.print(method[i].getName()+" ");
      System.out.print("(");
      for(int j=0;j<para.length;++j){
        System.out.print(para[j].getName()+" "+"arg"+j);
        if(j<para.length-1){
          System.out.print(",");
        }
      }
      Class<?> exce[]=method[i].getExceptionTypes();
      if(exce.length>0){
        System.out.print(") throws ");
        for(int k=0;k<exce.length;++k){
          System.out.print(exce[k].getName()+" ");
          if(k<exce.length-1){
            System.out.print(",");
          }
        }
      }else{
        System.out.print(")");
      }
      System.out.println();
    }
  }
}
【運行結果】:

java反射深入剖析(推薦)

【案例】接下來讓我們取得其他類的全部屬性吧,最后我講這些整理在一起,也就是通過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
26
27
28
29
30
31
32
33
34
class hello {
  public static void main(String[] args) {
    Class<?> demo = null;
    try {
      demo = Class.forName("Reflect.Person");
    } catch (Exception e) {
      e.printStackTrace();
    }
    System.out.println("===============本類屬性========================");
    // 取得本類的全部屬性
    Field[] field = demo.getDeclaredFields();
    for (int i = 0; i < field.length; i++) {
      // 權限修飾符
      int mo = field[i].getModifiers();
      String priv = Modifier.toString(mo);
      // 屬性類型
      Class<?> type = field[i].getType();
      System.out.println(priv + " " + type.getName() + " "
          + field[i].getName() + ";");
    }
    System.out.println("===============實現的接口或者父類的屬性========================");
    // 取得實現的接口或者父類的屬性
    Field[] filed1 = demo.getFields();
    for (int j = 0; j < filed1.length; j++) {
      // 權限修飾符
      int mo = filed1[j].getModifiers();
      String priv = Modifier.toString(mo);
      // 屬性類型
      Class<?> type = filed1[j].getType();
      System.out.println(priv + " " + type.getName() + " "
          + filed1[j].getName() + ";");
    }
  }
}

【運行結果】:

===============本類屬性========================
private java.lang.String sex;
===============實現的接口或者父類的屬性========================
public static final java.lang.String name;
public static final int age;

【案例】其實還可以通過反射調用其他類中的方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class hello {
  public static void main(String[] args) {
    Class<?> demo = null;
    try {
      demo = Class.forName("Reflect.Person");
    } catch (Exception e) {
      e.printStackTrace();
    }
    try{
      //調用Person類中的sayChina方法
      Method method=demo.getMethod("sayChina");
      method.invoke(demo.newInstance());
      //調用Person的sayHello方法
      method=demo.getMethod("sayHello", String.class,int.class);
      method.invoke(demo.newInstance(),"Rollen",20);
       
    }catch (Exception e) {
      e.printStackTrace();
    }
  }
}

【運行結果】:

hello ,china
Rollen  20

【案例】調用其他類的set和get方法

?
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
class hello {
  public static void main(String[] args) {
    Class<?> demo = null;
    Object obj=null;
    try {
      demo = Class.forName("Reflect.Person");
    } catch (Exception e) {
      e.printStackTrace();
    }
    try{
     obj=demo.newInstance();
    }catch (Exception e) {
      e.printStackTrace();
    }
    setter(obj,"Sex","男",String.class);
    getter(obj,"Sex");
  }
 
  /**
   * @param obj
   *      操作的對象
   * @param att
   *      操作的屬性
   * */
  public static void getter(Object obj, String att) {
    try {
      Method method = obj.getClass().getMethod("get" + att);
      System.out.println(method.invoke(obj));
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
 
  /**
   * @param obj
   *      操作的對象
   * @param att
   *      操作的屬性
   * @param value
   *      設置的值
   * @param type
   *      參數的屬性
   * */
  public static void setter(Object obj, String att, Object value,
      Class<?> type) {
    try {
      Method method = obj.getClass().getMethod("set" + att, type);
      method.invoke(obj, value);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}// end class

【運行結果】:

【案例】通過反射操作屬性

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class hello {
  public static void main(String[] args) throws Exception {
    Class<?> demo = null;
    Object obj = null;
 
    demo = Class.forName("Reflect.Person");
    obj = demo.newInstance();
 
    Field field = demo.getDeclaredField("sex");
    field.setAccessible(true);
    field.set(obj, "男");
    System.out.println(field.get(obj));
  }
}// end class

【案例】通過反射取得并修改數組的信息:

?
1
2
3
4
5
6
7
8
9
10
11
12
import java.lang.reflect.*;
class hello{
  public static void main(String[] args) {
    int[] temp={1,2,3,4,5};
    Class<?>demo=temp.getClass().getComponentType();
    System.out.println("數組類型: "+demo.getName());
    System.out.println("數組長度 "+Array.getLength(temp));
    System.out.println("數組的第一個元素: "+Array.get(temp, 0));
    Array.set(temp, 0, 100);
    System.out.println("修改之后數組第一個元素為: "+Array.get(temp, 0));
  }
}

【運行結果】:

數組類型: int
數組長度  5
數組的第一個元素: 1
修改之后數組第一個元素為: 100

【案例】通過反射修改數組大小

?
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
class hello{
  public static void main(String[] args) {
    int[] temp={1,2,3,4,5,6,7,8,9};
    int[] newTemp=(int[])arrayInc(temp,15);
    print(newTemp);
    System.out.println("=====================");
    String[] atr={"a","b","c"};
    String[] str1=(String[])arrayInc(atr,8);
    print(str1);
  }
   
  /**
   * 修改數組大小
   * */
  public static Object arrayInc(Object obj,int len){
    Class<?>arr=obj.getClass().getComponentType();
    Object newArr=Array.newInstance(arr, len);
    int co=Array.getLength(obj);
    System.arraycopy(obj, 0, newArr, 0, co);
    return newArr;
  }
  /**
   * 打印
   * */
  public static void print(Object obj){
    Class<?>c=obj.getClass();
    if(!c.isArray()){
      return;
    }
    System.out.println("數組長度為: "+Array.getLength(obj));
    for (int i = 0; i < Array.getLength(obj); i++) {
      System.out.print(Array.get(obj, i)+" ");
    }
  }
}

【運行結果】:

數組長度為: 15
1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 =====================
數組長度為: 8
a b c null null null null null


動態代理

【案例】首先來看看如何獲得類加載器:

?
1
2
3
4
5
6
7
8
9
class test{
   
}
class hello{
  public static void main(String[] args) {
    test t=new test();
    System.out.println("類加載器 "+t.getClass().getClassLoader().getClass().getName());
  }
}

【程序輸出】:

類加載器  sun.misc.Launcher$AppClassLoader

其實在java中有三種類類加載器。

1)Bootstrap ClassLoader 此加載器采用c++編寫,一般開發中很少見。

2)Extension ClassLoader 用來進行擴展類的加載,一般對應的是jre\lib\ext目錄中的類

3)AppClassLoader 加載classpath指定的類,是最常用的加載器。同時也是java中默認的加載器。

如果想要完成動態代理,首先需要定義一個InvocationHandler接口的子類,已完成代理的具體操作。

?
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
package Reflect;
import java.lang.reflect.*;
 
//定義項目接口
interface Subject {
  public String say(String name, int age);
}
 
// 定義真實項目
class RealSubject implements Subject {
  @Override
  public String say(String name, int age) {
    return name + " " + age;
  }
}
 
class MyInvocationHandler implements InvocationHandler {
  private Object obj = null;
 
  public Object bind(Object obj) {
    this.obj = obj;
    return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
        .getClass().getInterfaces(), this);
  }
 
  @Override
  public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable {
    Object temp = method.invoke(this.obj, args);
    return temp;
  }
}
 
class hello {
  public static void main(String[] args) {
    MyInvocationHandler demo = new MyInvocationHandler();
    Subject sub = (Subject) demo.bind(new RealSubject());
    String info = sub.say("Rollen", 20);
    System.out.println(info);
  }
}

【運行結果】:
Rollen  20

類的生命周期

在一個類編譯完成之后,下一步就需要開始使用類,如果要使用一個類,肯定離不開JVM。在程序執行中JVM通過裝載,鏈接,初始化這3個步驟完成。

類的裝載是通過類加載器完成的,加載器將.class文件的二進制文件裝入JVM的方法區,并且在堆區創建描述這個類的java.lang.Class對象。用來封裝數據。 但是同一個類只會被類裝載器裝載以前

鏈接就是把二進制數據組裝為可以運行的狀態。
 
鏈接分為校驗,準備,解析這3個階段

校驗一般用來確認此二進制文件是否適合當前的JVM(版本),

準備就是為靜態成員分配內存空間,。并設置默認值

解析指的是轉換常量池中的代碼作為直接引用的過程,直到所有的符號引用都可以被運行程序使用(建立完整的對應關系)

完成之后,類型也就完成了初始化,初始化之后類的對象就可以正常使用了,直到一個對象不再使用之后,將被垃圾回收。釋放空間。

當沒有任何引用指向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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
 * @author Rollen-Holt 設計模式之 工廠模式
 */
 
interface fruit{
  public abstract void eat();
}
 
class Apple implements fruit{
  public void eat(){
    System.out.println("Apple");
  }
}
 
class Orange implements fruit{
  public void eat(){
    System.out.println("Orange");
  }
}
 
// 構造工廠類
// 也就是說以后如果我們在添加其他的實例的時候只需要修改工廠類就行了
class Factory{
  public static fruit getInstance(String fruitName){
    fruit f=null;
    if("Apple".equals(fruitName)){
      f=new Apple();
    }
    if("Orange".equals(fruitName)){
      f=new Orange();
    }
    return f;
  }
}
class hello{
  public static void main(String[] a){
    fruit f=Factory.getInstance("Orange");
    f.eat();
  }
 
}

這樣,當我們在添加一個子類的時候,就需要修改工廠類了。如果我們添加太多的子類的時候,改的就會很多。

現在我們看看利用反射機制:

?
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
package Reflect;
 
interface fruit{
  public abstract void eat();
}
 
class Apple implements fruit{
  public void eat(){
    System.out.println("Apple");
  }
}
 
class Orange implements fruit{
  public void eat(){
    System.out.println("Orange");
  }
}
 
class Factory{
  public static fruit getInstance(String ClassName){
    fruit f=null;
    try{
      f=(fruit)Class.forName(ClassName).newInstance();
    }catch (Exception e) {
      e.printStackTrace();
    }
    return f;
  }
}
class hello{
  public static void main(String[] a){
    fruit f=Factory.getInstance("Reflect.Apple");
    if(f!=null){
      f.eat();
    }
  }
}

現在就算我們添加任意多個子類的時候,工廠類就不需要修改。

上面的愛嗎雖然可以通過反射取得接口的實例,但是需要傳入完整的包和類名。而且用戶也無法知道一個接口有多少個可以使用的子類,所以我們通過屬性文件的形式配置所需要的子類。

下面我們來看看: 結合屬性文件的工廠模式

首先創建一個fruit.properties的資源文件,

內容為:

?
1
2
apple=Reflect.Apple
orange=Reflect.Orange

然后編寫主類代碼:

?
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
package Reflect;
 
import java.io.*;
import java.util.*;
 
interface fruit{
  public abstract void eat();
}
 
class Apple implements fruit{
  public void eat(){
    System.out.println("Apple");
  }
}
 
class Orange implements fruit{
  public void eat(){
    System.out.println("Orange");
  }
}
 
//操作屬性文件類
class init{
  public static Properties getPro() throws FileNotFoundException, IOException{
    Properties pro=new Properties();
    File f=new File("fruit.properties");
    if(f.exists()){
      pro.load(new FileInputStream(f));
    }else{
      pro.setProperty("apple", "Reflect.Apple");
      pro.setProperty("orange", "Reflect.Orange");
      pro.store(new FileOutputStream(f), "FRUIT CLASS");
    }
    return pro;
  }
}
 
class Factory{
  public static fruit getInstance(String ClassName){
    fruit f=null;
    try{
      f=(fruit)Class.forName(ClassName).newInstance();
    }catch (Exception e) {
      e.printStackTrace();
    }
    return f;
  }
}
class hello{
  public static void main(String[] a) throws FileNotFoundException, IOException{
    Properties pro=init.getPro();
    fruit f=Factory.getInstance(pro.getProperty("apple"));
    if(f!=null){
      f.eat();
    }
  }
}
【運行結果】:Apple

以上這篇java反射深入剖析(推薦)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本丰满www色 | 国产裸露片段精华合集链接 | 亚洲精品午夜久久aaa级久久久 | 免费视频观看 | 男女乱淫真视频播放网站 | 好大好猛好爽好深视频免费 | bl文全肉高h湿被灌尿 | 日韩欧美成末人一区二区三区 | 成人午夜剧场 | 麻豆在线md0087免费 | 亚洲欧美优优色在线影院 | 亚洲va久久久噜噜噜久久狠狠 | 免费91麻豆精品国产自产在线观看 | 免费一级毛片完整版在线看 | 欧美人妖另类性hd | piss美女厕所小便 | 成年人在线视频观看 | 免费看视频高清在线观看 | 精品国产中文字幕在线视频 | 学生小泬无遮挡女HD | 久久精品手机观看 | 欧美一区二区三区高清不卡tv | 22222色男人的天堂 | 人体欣赏孕妇季玥图片 | 波多野 在线| 欧美色图日韩色图 | 日韩性公交车上xxhd免费 | 青青五月天| 草莓茄子丝瓜番茄小蝌蚪 | 色综七七久久成人影 | 精品国产理论在线观看不卡 | 日本wwxx护士 | 精品在线99 | 思思91精品国产综合在线 | 久久精品亚洲牛牛影视 | 欧美整片完整片视频在线 | 亚洲精品色综合久久 | 国产午夜永久福利视频在线观看 | 天堂樱桃bt在线www | 久热这里只有精品99国产6 | 5555国产在线观看精品 |