I am trying to find the type (Interface or class) of the "Class" instance. I can find isInterface() or isEnum(). But I want to check whether this is a class or not. WHY there is no method like "isClass()"? any help??
I have this code:
interface A {
}
class B {
}
public class ReflectionDemo {
public static void main(String[] argv) throws Exception {
Class a = A.class;
System.out.println(a.getCanonicalName());
System.out.println(a.getSimpleName());
System.out.println(a.isInterface());
System.out.println(a.isEnum());
Class b = B.class;
System.out.println(b.getCanonicalName());
System.out.println(b.getSimpleName());
System.out.println(b.isInterface());
System.out.println(b.isEnum());
}
}
Misread the question. Given that every type in Java is either a primitive, an interface, a class, or an array, you just need:
System.out.println(!b.isPrimitive() && !b.isInterface() && !b.isArray());
That treats enums as classes, by the way - you could exclude those in the same way, if you want.
Related
I'm trying to achieve the following:
I have a parent class, with some logic. In the child class, I "redefine" constants/properties. Is there any way to make the child properties accessible by methods defined in the parent class? Or to be more specific - is there any way to force the "out" method to write extended rather than base in the following example?
public class BaseTest {
public static final String x = "base";
public void out() {
System.out.println(x);
}
}
public class ExtendedTest extends BaseTest{
public static final String x = "extended";
}
public class Main {
public static void main(String[] args) {
BaseTest base = new BaseTest();
ExtendedTest extended = new ExtendedTest();
base.out(); // base (as expected)
extended.out(); // base (extended expected)
System.out.println(extended.x); // extended (as expected)
}
}
I come mainly from the world of PHP, where this approach works just fine. Dunno if I'm missing something or if the very design of Java does not allow this.
Thank you.
Note: This is not important whether the property is static or not. I just wanted to be able to override a property of any kind in a child class (just like I can override a method) which, on basis of the answers I've received so far, doesn't seem to be possible in Java. In PHP it is absolutely possible and that was why I asked the question.
static fields are not subject to inheritance. The x in the body of the out() method refers to BaseTest.x. Since you are not overriding out(), the body of the out() method still prints the value of BaseTest.x.
Static members are resolved at compile-time, and adding an ExtendedTest.x does not affect the also-existing BaseTest.x, which is what the BaseTest#out() method is linked to.
To accomplish what you're wanting, you need an overridden method:
public class BaseTest {
public String x() {
return "base";
}
public final void out() {
System.out.println(x());
}
}
public class ExtendedTest extends BaseTest {
#Override
public String x() {
return "extended";
}
}
This pattern is commonly used with an abstract method in the base class or interface to require the subclass to define an attribute such as a name or a key.
I am studying for my BS, and my professor has given me a task, he said: Create a class without using any access modifier or interface keyword whose object can't be created.
I went through Google but can't find the solution. How can this be done in Java?
Enums are classes (JLS§8.9) that cannot be instantiated and cannot be subclassed; just create one without any values:
enum Foo {}
Other possibilities depending on interpretation:
JonK and T.J. Crowder considered throwing an exception from the constructor:
final class Example {
Example() {
throw new Exception();
}
}
But nick zoum pointed out that an instance is still created and exists, briefly, prior to the exception, even though it cannot (in the example above) be retained.
nick zoum considered abstract:
abstract class Example {
}
...but T.J. Crowder pointed out that abstract classes can be subclassed (they cannot be final), and a subclass instance "is a" superclass instance.
I'm not a Java person, but other answers gave me this idea:
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
Object o = new Problematic();
// unreachable
}
}
class Problematic
{
static
{
int i = 1 / 0 ;
}
}
Try it on ideone
I'm pretty sure there's no way of making a Problematic and surviving...
(Note that when I tried throw new Exception(); in the static initializer it wouldn't compile)
Have you tried the keyword abstract?
For example:
abstract class Test{}
Of course this can be overwritten, so please check this answer for a more foolproof design.
Without hearing exactly how your professor phrased it, "without using any access-modifier" might mean they are attempting to teach you how the "default" access modifier works?
In which case:
package mypackage.nocreate;
class MyClass {
}
And then:
package mypackage;
import mypackage.nocreate.MyClass;
public class Test {
public static void main(String[] args) {
new MyClass(); // not allowed - in a different package
}
}
You could argue that - in the source code at least - that doesn't use any access modifier :)
Anonymous inner class should be the answer.
Example:
public abstract class HelloWorld{
abstract void x();
public static void main(String []args){
System.out.println("Hello World");
HelloWorld h = new HelloWorld(){
void x(){
System.out.println(" ");
}
};
h.x();
}
}
A class is created, but it's name is decided by the compiler which extends the HelloWorld class and provides the implementation of the x() method.
I took the following code from the K&B book "SCJP Sun Certified Programmer for Java 6 Study Guide":
class A { // 1
void m() {
System.out.println("outer");
}
}
public class TestInners {
public static void main(String[] args) {
new TestInners().go();
}
void go() {
new A().m();
class A { // 2
void m() {
System.out.println("inner");
}
}
}
class A { // 3
void m() {
System.out.println("middle");
}
}
}
As stated in the book, this code prints "middle". I infer that the class declaration marked as "3" is shadowing the one marked as "1", which is external to TestInners class.
If the classes were in different packages, I could resolve the ambiguity by qualifying one of them with the package name. But in this case the classes are not only in the same package but in the same file. How can I get an instance of the external class?
I saw the same question here but the accepted answer implies to modify the code adding an enclosing class to the whole thing. My question is how to get the instance using any type of qualifier or reference, if it's even possible.
Assuming your class is in package com.test, all you need to do is use
new com.test.A().m();
using the fully qualified name of the class.
If your classes are in the default package, ie. no package declaration, then you are out of luck and can't access the outer A.
In C++, you can explicitly address global scope by prefixing your symbol with ::, however, Java does not have such a thing.
So if you really want to get the outer A, you have to bite the bullet and do some other sort of enclosure, by for example wrapping it in another class or package.
EDIT: Here is another reason why.
object of innner-A can't be created before defining it.so use new A().m(); after define innner-A inside go() to access inner class object.
void go() {
class A {
void m() {
System.out.println("inner");
}
}
new A().m();
}
to access outer-A you have to append package name,in default package it is impossible to access outer-A.
java.lang.Class has methods to test if a given type is:
isAnnotation
isArray
isEnum
isInterface
isPrimitive
but how does one test that an object of type Class (instanceof Class is true) represents a declared, non-abstract class rather than in interface, enum, primitive, array, etc. For example:
package org.acme;
public class ACME {
public ACME() {
}
public static void main(String[] args) {
Class clazz = Class.forName("org.acme.ACME");
// Expected I could use a clazz.isClass().
}
}
I was looking for a isClass method, but there isn't.
Update
I see the confusion generated by my question - while some people got my question.
I did some further research and found out that in .NET
http://msdn.microsoft.com/en-us/library/system.type.isclass.aspx,
there this is a isClass member and I was looking for a similar method in java.lang.Class.
I now know that the equivalent in Java is to test for all the other isXXX methods to find out that it's not a class.
It seems there's a disconnect in your question. Everything is a class (except primitives - the isPrimitive() method actually means the class is an autobox type).
Class clazz = Class.forName("org.acme.ACME");
// Expected I could use a clazz.isClass().
That would be redundant. You already know it's a class. Because you have an instance of Class.
It would appear that for some reason you would like to know it's not any of the types of classes the methods you list tell you, in which case you'd simply do a check to negate those options:
if (!clazz.isAnnotation() &&
!clazz.isArray() /* && ... etc */ )
{
// Not any of those things.
}
Class objects are singletons. Therefore, if you have an instance of any type, you can test that it is an exact class instance using:
theInstance.getClass() == TheTargetClass.class
As to testing whether a class is a "full" class, just negate all the test you mentioned. This first test is already an efficient filter... And do not forget .isSynthetic().
Not so readable but
object.getClass().getModifiers() < 30 //abstract classes are not included
or in a more readable way:
object.getClass().getModifiers() < Modifier.PROTECTED + Modifier.STATIC + Modifier.FINAL
seems to work, being more neat (but more obscure) than
!(!isInterface() && !isEnum() && !is ...)
A simple class can only have these modifiers:
public static final int PUBLIC = 0x00000001;
public static final int PRIVATE = 0x00000002;
public static final int PROTECTED = 0x00000004;
public static final int STATIC = 0x00000008;
public static final int FINAL = 0x00000010;
while abstract, interafce, enum or annotation has larger values (over 200).
You can see the Modifiers of a class by calling Modifier.toString(myClass.getModifiers()). The getModifiers() class returns the sum in hexa of all modifiers (as I have tested on some values; the implementation is native).
A partial solution:
You can try to execute the Class's newInstance method. If the class is abstract or an interface an InstantiationException will be thrown- Otherwise, you're good.
The problem is that creating a new instance in a class you don't know might have unknown effects, or the class might not have a default constructor.
Two options that should work for you:
You can do class instanceof Object
You can check all the other is...() methods. If they are all false you have a class.
Is it possible to create an anonymous class in Java like this:
public static void main(String[] args) {
AnonymousClass a = new AnonymousClass() {
int whatever = 1;
};
System.out.println(a.whatever);
}
I thought that this would be working but it doesn't. Do I misunderstand something with anonymous classes or is there only a syntax error?
You can do it this way:
public static void main(String[] args) {
System.out.println(new Object() {
int whatever = 1;
}.whatever);
}
That is, you can only dereference the fields and method directly from the instantiation expression. [Edit: Per the comments, you can use it where the compiler infers the type for you - which happens to be the instantion expression, or as a return value from a generic method you pass it to.] You can't store it in a variable and use fields/methods there, so it's not as useful as anonymous classes in e.g. C#.
Edit: You can, as previously stated by others, declare a method-local class:
public static void main(String[] args) {
class Local {
int whatever = 1;
}
Local local = new Local();
System.out.println(local);
}
Slightly wordy, though, and like non-static inner classes and regular anonymous classes, it retains an implicit reference to the enclosing this (in non-static methods).
If it was possible, we would not call them anonymous anymore: your example defines a class with a name: Anonymous. You may define an inner class with a name like this:
public static void main(String[] args) {
class NotAnonymous {
public int whatever = 1;
}
NotAnonymous na = new NotAnonymous();
System.out.println(na.whatever);
}
For this to work, AnonymousClass needs to be an Interface or a Class:
private interface AnonymousClass {
}
public static void main(String[] args) {
AnonymousClass a = new AnonymousClass() {
int whatever = 1;
};
System.out.println(a.whatever); // this won't work
}
EDIT
Corrected, as correctly stated in the comment, whatever won't accessible / present.
You are referring original anonymous class instance, which has no field "whatever" - so you can not reference it this way.
You can create your class like this, sure. However, the a.whatever call will fail, because the object type is still AnonymousClass, and it does not define whatever as an attribute.
If you overwrite some method or attribute that is already defined in the AnonymousClass class or interface, the object will use your implementation from the anonymous class instead of the old one, but not if you introduce new methods or attributes.