为什么在外部 class 的 <> 括号内写一个内部私有 class 会出错?
Why writing an Inner Private class inside <> bracket of outer class makes error?
我正在尝试将私有 class 插入到外部 class 声明的括号(泛型)中并出现下一个错误:“com.example.gridrecyclerview.RecyclerViewAdapter.VieHolder 在 [=20 中具有私有访问权限=]"
将内部 class 更改为 public 一切正常。有人可以向我解释这个问题。
附代码:
package com.example.gridrecyclerview;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import java.util.Random;
public class RecyclerViewAdapter extends RecyclerView.Adapter <RecyclerViewAdapter.ViewHolder> {
Context context;
List<ModelItem> modelItemList;
public RecyclerViewAdapter(Context context, List<ModelItem> modelItemList)
{
this.context = context;
this.modelItemList = modelItemList;
}
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(context).inflate(R.layout.rc_item,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position)
{
Log.e("onBindViewHolder ","onBindViewHolder");
ModelItem modelItem = modelItemList.get(position);
holder.firstNameTextView.setText(modelItem.getFirstName());
holder.secondNameText.setText(modelItem.getLastName());
}
@Override
public int getItemCount()
{
return modelItemList.size();
}
private class ViewHolder extends RecyclerView.ViewHolder
{
TextView firstNameTextView;
TextView secondNameText;
public ViewHolder(@NonNull View itemView)
{
super(itemView);
firstNameTextView = itemView.findViewById(R.id.first_name);
secondNameText = itemView.findViewById(R.id.second_name);
}
}
}
你不能这样做,因为你正在将私有 class 传递给“RecyclerView.Adapter”class。换句话说,ViewHolder class 仅在 RecyclerViewAdapter class.
内部可用
PS:您可以将此 class 创建为新的 Class,然后将其传递给“RecyclerView.Adapter” class 或将其更改为 public范围。
要回答这个问题你应该知道当你在Java中使用泛型时幕后发生了什么,泛型在编译时被检查并且在运行时没有泛型类型这被称为类型擦除,当你编译你的程序,所有泛型都是特定类型的种姓。想象一下你的 RecyclerView.Adapter
class 是这样的:
public class Adapter<T> {
T view;
public T getView() {
return view;
}
public void setView(T view) {
this.view = view;
}
}
假设您已经像以前一样定义了 RecyclerViewAdapter
class:
现在让我们从两个角度讨论这个问题:
- 程序员
- 编译器
作为程序员想象在另一个 class 中的某处,您创建 RecyclerViewAdapter
class 的实例如下并在该对象上调用 getView():
RecyclerViewAdapter recycler = RecyclerViewAdapter();
? object = recycler.getView()
你放在这里的是什么类型的对象?
显然你不能放 RecyclerViewAdapter.ViewHolder
因为它对 RecyclerViewAdapter
是私有的,你不能在其他地方使用它。
现在让我们从编译器的角度考虑这个问题:
编译泛型时,编译器使用擦除并将您的代码编译成这样:
RecyclerViewAdapter recycler = RecyclerViewAdapter();
? object = (RecyclerViewAdapter.ViewHolder)recycler.getView();
在这里你可以看到编译器在编译时转换你的对象的类型((RecyclerViewAdapter.ViewHolder)recycler.getView()
)。但是编译器有可能在这里做这样的事情吗?
当然不是因为 RecyclerViewAdapter.ViewHolder
对 RecyclerViewAdapter
class 是私有的,而这段代码是在另一个 class.
中编写的
根据Java-Spec页-164中的可访问性规则,声明的私有成员只能在顶级class的主体内访问。我希望 class 的主体不是它的定义。
**
否则,成员或构造函数被声明为私有,当且仅当它发生在包含成员或构造函数声明的顶层 class (§7.6) 的主体内时才允许访问.
**
我正在尝试将私有 class 插入到外部 class 声明的括号(泛型)中并出现下一个错误:“com.example.gridrecyclerview.RecyclerViewAdapter.VieHolder 在 [=20 中具有私有访问权限=]"
将内部 class 更改为 public 一切正常。有人可以向我解释这个问题。 附代码:
package com.example.gridrecyclerview;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import java.util.Random;
public class RecyclerViewAdapter extends RecyclerView.Adapter <RecyclerViewAdapter.ViewHolder> {
Context context;
List<ModelItem> modelItemList;
public RecyclerViewAdapter(Context context, List<ModelItem> modelItemList)
{
this.context = context;
this.modelItemList = modelItemList;
}
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(context).inflate(R.layout.rc_item,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position)
{
Log.e("onBindViewHolder ","onBindViewHolder");
ModelItem modelItem = modelItemList.get(position);
holder.firstNameTextView.setText(modelItem.getFirstName());
holder.secondNameText.setText(modelItem.getLastName());
}
@Override
public int getItemCount()
{
return modelItemList.size();
}
private class ViewHolder extends RecyclerView.ViewHolder
{
TextView firstNameTextView;
TextView secondNameText;
public ViewHolder(@NonNull View itemView)
{
super(itemView);
firstNameTextView = itemView.findViewById(R.id.first_name);
secondNameText = itemView.findViewById(R.id.second_name);
}
}
}
你不能这样做,因为你正在将私有 class 传递给“RecyclerView.Adapter”class。换句话说,ViewHolder class 仅在 RecyclerViewAdapter class.
内部可用PS:您可以将此 class 创建为新的 Class,然后将其传递给“RecyclerView.Adapter” class 或将其更改为 public范围。
要回答这个问题你应该知道当你在Java中使用泛型时幕后发生了什么,泛型在编译时被检查并且在运行时没有泛型类型这被称为类型擦除,当你编译你的程序,所有泛型都是特定类型的种姓。想象一下你的 RecyclerView.Adapter
class 是这样的:
public class Adapter<T> {
T view;
public T getView() {
return view;
}
public void setView(T view) {
this.view = view;
}
}
假设您已经像以前一样定义了 RecyclerViewAdapter
class:
现在让我们从两个角度讨论这个问题:
- 程序员
- 编译器
作为程序员想象在另一个 class 中的某处,您创建 RecyclerViewAdapter
class 的实例如下并在该对象上调用 getView():
RecyclerViewAdapter recycler = RecyclerViewAdapter();
? object = recycler.getView()
你放在这里的是什么类型的对象?
显然你不能放 RecyclerViewAdapter.ViewHolder
因为它对 RecyclerViewAdapter
是私有的,你不能在其他地方使用它。
现在让我们从编译器的角度考虑这个问题:
编译泛型时,编译器使用擦除并将您的代码编译成这样:
RecyclerViewAdapter recycler = RecyclerViewAdapter();
? object = (RecyclerViewAdapter.ViewHolder)recycler.getView();
在这里你可以看到编译器在编译时转换你的对象的类型((RecyclerViewAdapter.ViewHolder)recycler.getView()
)。但是编译器有可能在这里做这样的事情吗?
当然不是因为 RecyclerViewAdapter.ViewHolder
对 RecyclerViewAdapter
class 是私有的,而这段代码是在另一个 class.
根据Java-Spec页-164中的可访问性规则,声明的私有成员只能在顶级class的主体内访问。我希望 class 的主体不是它的定义。
** 否则,成员或构造函数被声明为私有,当且仅当它发生在包含成员或构造函数声明的顶层 class (§7.6) 的主体内时才允许访问. **