此问题的已接受答案描述了如何T在Generic<T>类中创建实例.这涉及将Class<T>参数传递给Generic构造函数并newInstance从中调用方法.
Generic<Bar>然后创建一个新实例,并Bar.class传入参数.
如果新Generic类的泛型类型参数不是某个已知的类,Bar但它本身是泛型类型参数,您会怎么做?假设我有一些其他类Skeet<J>,我想Generic<J>从该类内部创建一个新实例.然后,如果我尝试传入,J.class我得到以下编译器错误:
cannot select from a type variable.
Run Code Online (Sandbox Code Playgroud)
有没有办法解决?
触发错误的代码的具体位是:
public class InputField<W extends Component & WidgetInterface>
extends InputFieldArray<W>
{
public InputField(String labelText)
{
super(new String[] {labelText}, W.class);
}
/* ... */
}
public class InputFieldArray<W extends Component & WidgetInterface>
extends JPanel
{
/* ... */
public InputFieldArray(String[] labelText, Class<W> clazz)
throws InstantiationException, IllegalAccessException
{ …Run Code Online (Sandbox Code Playgroud) 关于包含静态抽象Java方法的不可能性存在许多问题.关于此的解决方法(设计缺陷/设计强度)也有很多.但我找不到任何关于我即将陈述的具体问题.
在我看来,制作Java的人和很多使用Java的人并没有像我和其他许多人那样思考静态方法 - 作为类函数或属于类的方法而不是任何对象.那么还有其他一些实现类函数的方法吗?
这是我的例子:在数学中,一个组是一组对象,可以使用某些操作*以某种合理的方式相互组合 - 例如,正实数在正常乘法下形成一组(x*y = x × y),并且整数组形成一组,其中"乘法"运算是加法(m*n = m + n).
在Java中对此进行建模的一种自然方法是为组定义接口(或抽象类):
public interface GroupElement
{
/**
/* Composes with a new group element.
/* @param elementToComposeWith - the new group element to compose with.
/* @return The composition of the two elements.
*/
public GroupElement compose(GroupElement elementToComposeWith)
}
Run Code Online (Sandbox Code Playgroud)
我们可以为上面给出的两个例子实现这个接口:
public class PosReal implements GroupElement
{
private double value;
// getter and setter for this field …Run Code Online (Sandbox Code Playgroud) 我被要求为用Java编写的现有shell/cmdline程序编写GUI,我想在GUI和原始程序之间创建一个抽象层,以便于添加不同的GUI(Web界面,例如,而不是桌面应用程序).目前,该计划的结构如下:

命令行选项被立即转换为一个Java散列表(以一个选项如-f opt到散列"-f=>opt".这些选项,然后用于建立environment对象,该对象的程序使用.
我想到的结构是:

在实线之后,这意味着GUI生成一个XML文件,其中包含与shell/cmdline选项相同的信息,然后用于设置environment选项.
问题是,我不太确定这是否是最好的工作方式(虚线,表示替代结构),我也不知道XML是否是正确的选择.
就目前而言,environment从中设置对象的程序options部分与使用它environment获取结果的部分位于相同的方法中.因此,实现将shell/cmdline参数直接送入程序的内容比实现将信息作为XML文件传递的结构更容易.我当然不想创建XML文件,然后将其转换为shell选项并将其转移到程序中,但是GUI可能更有意义生成shell选项而不是创建XML.
据我所知,使用XML文件的主要优点是它使未来开发人员的工作更容易,因为他们可以使用现有的库来创建XML文件,而不必担心-a opt1 -b opt2 -c opt3 [...]正确的语法.
另一方面,我听说尝试创建自己的XML语言是不容忽视的(尽管程序可以将数据存储在没有DTD的XML文件中,甚至可以告诉我的架构).
我的方法或多或少是正确的吗?或者我使用完全不合适的工具来完成我正在尝试的工作?
这是一个一般性的问题,但我会首先给你我的具体问题:
我正在为我的程序编写一个GUI,用于一个程序,该程序将采用框架的形式,其中放置了各种小部件(标签,文本字段等).它最初将使用该javax.swing库,但我在库和GUI本身之间设置了一层抽象,以便更容易创建执行相同操作的Web应用程序.
我希望有一个代表GUI布局的类:也就是说,它应该包含有关各种标签,按钮等放置在内容窗格中的位置的所有信息.目前,我正在考虑的实施如下:
class Layout
{
public MyLabel titleLabel;
public myTextField sequenceTextField;
[...]
public void drawTitleLabel()
{
titleLabel = new MyLabel("This is the title.");
titleLabel.setLocation(wherever);
titleLabel.draw();
}
public void drawSequenceTextField()
{
sequenceTextField = new MyTextField();
[...]
sequenceTextField.draw();
}
[...]
public void drawGuiFrame()
{
drawTitleLabel();
drawSequenceTextField();
[...]
}
}
Run Code Online (Sandbox Code Playgroud)
因此,我将内容窗格上的每个窗口小部件声明为该类的字段Layout,然后创建drawWidgetName绘制每个窗口小部件的方法.最后,我创建了一个方法来调用每个draw...方法以绘制整个GUI.
但这似乎是错误的.这些draw...方法感觉好像它们应该是各个小部件本身的方法,而不是整个GUI的大规模布局.这表明,我应该创建单独的类TitleLabel,SequenceTextField等等,每一个draw方法,然后只是有一个drawGuiFrame在方法Layout调用所有这些类的draw方法(我甚至可以创建一个抽象类,这些新类可以扩展).
这会有一些其他直接的好处.假设我想要合并一个复选框系统以及我的标签和文本区域.然后,我可以宣布,作为其自己的类,并给它的属性isOptionA,isOptionB等等,以记录其复选框选中了.
但是我有点不愿意以这种方式实现GUI,原因有两个.首先,创建这么多新类会使代码库与大量小.java文件混乱.其次,这些将是非常"单一使用"类:我永远不会再使用代码,因为类将纯粹为这个特定的GUI设计. …
当我用//Java 编写注释时,按Enter键,vim有助于//在下一行的开头添加一个.
// This is the first line of my comment <CR>
// <-- these were added automatically by auto-comment.
Run Code Online (Sandbox Code Playgroud)
正如我所说,这是有用的行为(我//用于多行注释,以便很容易注释掉大块代码/*...*/,并/**...*/仅用于Javadoc注释).但是当我到达评论结束时,我必须按三次退格键才能摆脱//我现在不再需要的行的开头.
是否有插入模式的键盘快捷键可以告诉Vim我不再写评论?或者我必须自己写?
以下代码编译:
import java.util.ArrayList;
public class ClassTest
{
private ArrayList<Class<? extends Interface1>> testClass =
new ArrayList<Class<? extends Interface1>>();
private interface Interface1 {}
}
Run Code Online (Sandbox Code Playgroud)
但是以下代码会产生六个错误:
import java.util.ArrayList;
public class ClassTest
{
private ArrayList<Class<? extends Interface1 & Interface2>> testClass =
new ArrayList<Class<? extends Interface1 & Interface2>>();
private interface Interface1 {}
private interface Interface2 {}
}
Run Code Online (Sandbox Code Playgroud)
错误:
ClassTest.java:5: > expected
private ArrayList<Class<? extends Interface1 & Interface2>> testClass =
^
ClassTest.java:5: ';' expected
private ArrayList<Class<? extends Interface1 & Interface2>> testClass =
^
ClassTest.java:5: <identifier> expected …Run Code Online (Sandbox Code Playgroud) 请原谅挑衅性问题标题.众所周知,你永远不应该在Java程序中使用公共字段(除了类似结构的类,你应该避免使用它).但人们谈论硬币的另一面 - 私人方法.
我看到它的方式是:如果你有私有方法,那么你正在编写本地程序代码.具有私有字段的Java类和调用许多私有方法的一些公共方法,以及具有全局变量和一些函数的C模块之间基本上没有区别,其中一些是在extern其他地方编写的(除了相当大的区别之外)你不能实例化一个C模块).鉴于很多关心良好Java实践的人都认为你应该尽可能远离程序性的工作,我很惊讶没有更多的指导方针限制私有方法的使用.
请注意,我不想暗示任何人都认为永远不应该使用私有方法(或者它们实际上和公共字段一样糟糕).但这是我的问题,我尽量做到尽可能客观:
我刚刚得到以下编译器错误:
./package/path/FrameScreenPosition.java:80: incompatible types
found : int
required: boolean
if (frame.getExtendedState() & Frame.MAXIMIZED_BOTH) {
^
Run Code Online (Sandbox Code Playgroud)
"扩展状态"是各种不同状态的按位掩码,例如最大化或图标化,我试图测试帧是否最大化.以下简短示例产生类似的错误:
public class BitTest
{
public static void main(String[] args)
{
int a = 1;
int c = 3;
if (a & c) {
System.out.println("This is right.");
}
}
}
Run Code Online (Sandbox Code Playgroud)
我所看到的一切都表明,按位运算符&不限于Java中的布尔变量,为什么我会收到错误消息?
以下程序(什么都不做)运行正常.
#include <stdio.h>
int main(int argc, char *argv[])
{
char *current_string = NULL;
fgets(current_string, 16, stdin);
return(0);
}
Run Code Online (Sandbox Code Playgroud)
但是,当我在GDB下运行它时,该fgets调用会触发分段错误.
Program received signal SIGSEGV, Segmentation fault.
0x000000332ec67ee0 in _IO_getline_info_internal () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6_6.9.x86_64
(gdb) backtrace
#0 0x000000332ec67ee0 in _IO_getline_info_internal () from /lib64/libc.so.6
#1 0x000000332ec66d29 in fgets () from /lib64/libc.so.6
#2 0x0000000000400536 in main (argc=1, argv=0x7fffffffd4e8) at test.c:7
Run Code Online (Sandbox Code Playgroud)
据我所知,我一直在关注该fgets函数的正确用法,我不明白发生了什么.我做错了什么?
我正在用gcc编译-gRHEL上的选项(用于调试信息).
注意: 我知道读取未初始化的字符串是未定义的行为。这个问题具体是关于 GCC 的实施。
\n我使用的是 GCC 版本 6.2.1,并且我观察到长度大于 100 左右的未初始化字符串被初始化为"". 读取未初始化的字符串是未定义的行为,因此编译器可以""根据需要随意将其设置为,并且当字符串足够长时,GCC 似乎会这样做。当然,我永远不会在生产代码中依赖这种行为 - 我只是好奇这种行为在 GCC 中来自哪里。如果它不在 GCC 代码中的某个地方,那么它不断发生就是一个非常奇怪的巧合。
如果我写下面的程序
\n/* string_initialization.c */\n#include <stdio.h>\n\nint main()\n{\n char short_string[10];\n char long_string[100];\n char long_long_string[1000];\n\n printf("%s\\n", short_string);\n printf("%s\\n", long_string);\n printf("%s\\n", long_long_string);\n\n return(0);\n}\nRun Code Online (Sandbox Code Playgroud)\n并用 GCC 编译并运行它,我得到:
\n$ ./string_initialization\n\xef\xbf\xbdQE\xef\xbf\xbd\n\n\n$\nRun Code Online (Sandbox Code Playgroud)\n(有时第一个字符串也是空的)。这表明如果字符串足够长,GCC 会将其初始化为"",但否则并不总是这样做。
如果我用 GCC 编译以下程序并运行它:
\n#include <stdio.h>\n\nint main()\n{\n char long_string[100];\n int i;\n\n for (i = 0 ; i < 100 ; ++i)\n {\n printf("%d …Run Code Online (Sandbox Code Playgroud) 乍一看,我本来希望能够演员
ArrayList<Class<? extends Interface1>>
Run Code Online (Sandbox Code Playgroud)
至
ArrayList<Class<?>>
Run Code Online (Sandbox Code Playgroud)
因为第二个显然是第一个限制较少的版本.但是,以下代码无法编译:
import java.util.ArrayList;
public class TypeInvocationConversionTest
{
private static ArrayList<Class<? extends Interface1>> classList;
private static ArrayList<Class<?>> lessRestrictiveClassList;
public static void main(String[] args)
{
classList = new ArrayList<Class<? extends Interface1>>();
lessRestrictiveClassList = (ArrayList<Class<?>>) classList;
}
private interface Interface1 {}
}
Run Code Online (Sandbox Code Playgroud)
但会产生错误
TypeInvocationConversionTest.java:12: inconvertible types
found : java.util.ArrayList<java.lang.Class<? extends TypeInvocationConversionTest.Interface1>>
required: java.util.ArrayList<java.lang.Class<?>>
lessRestrictiveClassList = (ArrayList<Class<?>>) classList;
^
Run Code Online (Sandbox Code Playgroud)
我不认为想要转换这两种类型是不合理的:为了激励,这里是一个更接近我实际处理的短程序(这段代码不能编译):
import java.util.ArrayList;
public class Mammal
{
public void produceMilk() {}
}
public class Reptile
{
public …Run Code Online (Sandbox Code Playgroud)